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*57309Shibler * @(#)hil.c 7.15 (Berkeley) 12/27/92 1541480Smckusick */ 1641480Smckusick 1756504Sbostic #include <sys/param.h> 1856504Sbostic #include <sys/conf.h> 1956504Sbostic #include <sys/proc.h> 2056504Sbostic #include <sys/user.h> 2156504Sbostic #include <sys/ioctl.h> 2256504Sbostic #include <sys/file.h> 2356504Sbostic #include <sys/tty.h> 2456504Sbostic #include <sys/systm.h> 2556504Sbostic #include <sys/uio.h> 2656504Sbostic #include <sys/kernel.h> 2741480Smckusick 2856504Sbostic #include <hp/dev/hilreg.h> 2956504Sbostic #include <hp/dev/hilioctl.h> 3056504Sbostic #include <hp/dev/hilvar.h> 3156504Sbostic #include <hp/dev/kbdmap.h> 3241480Smckusick 3356504Sbostic #include <machine/cpu.h> 3441480Smckusick 3556504Sbostic #include <vm/vm_param.h> 3656504Sbostic #include <vm/vm_map.h> 3756504Sbostic #include <vm/vm_kern.h> 3856504Sbostic #include <vm/vm_page.h> 3956504Sbostic #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 */ 163*57309Shibler if (p->p_md.md_flags & MDP_HPUX) { 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 218*57309Shibler if (p && (p->p_md.md_flags & MDP_HPUX) == 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, 32255070Spendry 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 384*57309Shibler if (p->p_md.md_flags & MDP_HPUX) 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 401*57309Shibler case OHILIOCRRT: 40241480Smckusick case HILIOCRRT: 40341480Smckusick /* Transfer the real time to the 8042 data buffer */ 40441480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL); 40541480Smckusick /* Read each byte of the real time */ 40641480Smckusick for (i = 0; i < 5; i++) { 40741480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READTIME + i, NULL, 40841480Smckusick 0, &hold); 40941480Smckusick data[4-i] = hold; 41041480Smckusick } 41141480Smckusick break; 41241480Smckusick 41341480Smckusick case HILIOCRT: 41441480Smckusick for (i = 0; i < 4; i++) { 41541480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF) + i, 41641480Smckusick NULL, 0, &hold); 41741480Smckusick data[i] = hold; 41841480Smckusick } 41941480Smckusick break; 42041480Smckusick 42141480Smckusick case HILIOCID: 42253923Shibler case OHILIOCID: 42341480Smckusick case HILIOCSC: 42441480Smckusick case HILIOCRN: 42541480Smckusick case HILIOCRS: 42641480Smckusick case HILIOCED: 42741480Smckusick send_hildev_cmd(hilp, device, (cmd & 0xFF)); 42841480Smckusick bcopy(hilp->hl_cmdbuf, data, hilp->hl_cmdbp-hilp->hl_cmdbuf); 42941480Smckusick break; 43041480Smckusick 43141480Smckusick case HILIOCAROFF: 43241480Smckusick case HILIOCAR1: 43341480Smckusick case HILIOCAR2: 43441480Smckusick if (hilp->hl_kbddev) { 43541480Smckusick hilp->hl_cmddev = hilp->hl_kbddev; 43641480Smckusick send_hildev_cmd(hilp, hilp->hl_kbddev, (cmd & 0xFF)); 43741480Smckusick hilp->hl_kbdflags &= ~(KBD_AR1|KBD_AR2); 43841480Smckusick if (cmd == HILIOCAR1) 43941480Smckusick hilp->hl_kbdflags |= KBD_AR1; 44041480Smckusick else if (cmd == HILIOCAR2) 44141480Smckusick hilp->hl_kbdflags |= KBD_AR2; 44241480Smckusick } 44341480Smckusick break; 44441480Smckusick 44541480Smckusick case HILIOCBEEP: 44641480Smckusick hilbeep(hilp, (struct _hilbell *)data); 44741480Smckusick break; 44841480Smckusick 44941480Smckusick case FIONBIO: 45041480Smckusick dptr = &hilp->hl_device[device]; 45141480Smckusick if (*(int *)data) 45241480Smckusick dptr->hd_flags |= HIL_NOBLOCK; 45341480Smckusick else 45441480Smckusick dptr->hd_flags &= ~HIL_NOBLOCK; 45541480Smckusick break; 45641480Smckusick 45741480Smckusick /* 45841480Smckusick * FIOASYNC must be present for FIONBIO above to work! 45941480Smckusick * (See fcntl in kern_descrip.c). 46041480Smckusick */ 46141480Smckusick case FIOASYNC: 46241480Smckusick break; 46341480Smckusick 46441480Smckusick case HILIOCALLOCQ: 46553923Shibler error = hilqalloc(hilp, (struct hilqinfo *)data); 46641480Smckusick break; 46741480Smckusick 46841480Smckusick case HILIOCFREEQ: 46953923Shibler error = hilqfree(hilp, ((struct hilqinfo *)data)->qid); 47041480Smckusick break; 47141480Smckusick 47241480Smckusick case HILIOCMAPQ: 47353923Shibler error = hilqmap(hilp, *(int *)data, device); 47441480Smckusick break; 47541480Smckusick 47641480Smckusick case HILIOCUNMAPQ: 47753923Shibler error = hilqunmap(hilp, *(int *)data, device); 47841480Smckusick break; 47941480Smckusick 48041480Smckusick case HILIOCHPUX: 48141480Smckusick dptr = &hilp->hl_device[device]; 48241480Smckusick dptr->hd_flags |= HIL_READIN; 48341480Smckusick dptr->hd_flags &= ~HIL_QUEUEIN; 48441480Smckusick break; 48541480Smckusick 48641480Smckusick case HILIOCRESET: 48741480Smckusick hilreset(hilp); 48841480Smckusick break; 48941480Smckusick 49041480Smckusick #ifdef DEBUG 49141480Smckusick case HILIOCTEST: 49241480Smckusick hildebug = *(int *) data; 49341480Smckusick break; 49441480Smckusick #endif 49541480Smckusick 49641480Smckusick default: 49741480Smckusick error = EINVAL; 49841480Smckusick break; 49941480Smckusick 50041480Smckusick } 50141480Smckusick hilp->hl_cmddev = 0; 50241480Smckusick return(error); 50341480Smckusick } 50441480Smckusick 50541480Smckusick #ifdef HPUXCOMPAT 50641480Smckusick /* ARGSUSED */ 50741480Smckusick hpuxhilioctl(dev, cmd, data, flag) 50841480Smckusick dev_t dev; 50941480Smckusick caddr_t data; 51041480Smckusick { 51153923Shibler register struct hilloop *hilp = &hilloop[HILLOOP(dev)]; 51241480Smckusick char device = HILUNIT(dev); 51341480Smckusick struct hilloopdev *dptr; 51441480Smckusick register int i; 51541480Smckusick u_char hold; 51641480Smckusick 51741480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 51841480Smckusick bzero((caddr_t)hilp->hl_cmdbuf, HILBUFSIZE); 51941480Smckusick hilp->hl_cmddev = device; 52041480Smckusick switch (cmd) { 52141480Smckusick 52241480Smckusick case HILSC: 52341480Smckusick case HILID: 52441480Smckusick case HILRN: 52541480Smckusick case HILRS: 52641480Smckusick case HILED: 52741480Smckusick case HILP1: 52841480Smckusick case HILP2: 52941480Smckusick case HILP3: 53041480Smckusick case HILP4: 53141480Smckusick case HILP5: 53241480Smckusick case HILP6: 53341480Smckusick case HILP7: 53441480Smckusick case HILP: 53541480Smckusick case HILA1: 53641480Smckusick case HILA2: 53741480Smckusick case HILA3: 53841480Smckusick case HILA4: 53941480Smckusick case HILA5: 54041480Smckusick case HILA6: 54141480Smckusick case HILA7: 54241480Smckusick case HILA: 54341480Smckusick send_hildev_cmd(hilp, device, (cmd & 0xFF)); 54441480Smckusick bcopy(hilp->hl_cmdbuf, data, hilp->hl_cmdbp-hilp->hl_cmdbuf); 54541480Smckusick break; 54641480Smckusick 54741480Smckusick case HILDKR: 54841480Smckusick case HILER1: 54941480Smckusick case HILER2: 55041480Smckusick if (hilp->hl_kbddev) { 55141480Smckusick hilp->hl_cmddev = hilp->hl_kbddev; 55241480Smckusick send_hildev_cmd(hilp, hilp->hl_kbddev, (cmd & 0xFF)); 55341480Smckusick hilp->hl_kbdflags &= ~(KBD_AR1|KBD_AR2); 55441480Smckusick if (cmd == HILIOCAR1) 55541480Smckusick hilp->hl_kbdflags |= KBD_AR1; 55641480Smckusick else if (cmd == HILIOCAR2) 55741480Smckusick hilp->hl_kbdflags |= KBD_AR2; 55841480Smckusick } 55941480Smckusick break; 56041480Smckusick 56141480Smckusick case EFTSBP: 56241480Smckusick /* Send four data bytes to the tone gererator. */ 56341480Smckusick send_hil_cmd(hilp->hl_addr, HIL_STARTCMD, data, 4, NULL); 56441480Smckusick /* Send the trigger beeper command to the 8042. */ 56541480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL); 56641480Smckusick break; 56741480Smckusick 56841480Smckusick case EFTRRT: 56941480Smckusick /* Transfer the real time to the 8042 data buffer */ 57041480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL); 57141480Smckusick /* Read each byte of the real time */ 57241480Smckusick for (i = 0; i < 5; i++) { 57341480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READTIME + i, NULL, 57441480Smckusick 0, &hold); 57541480Smckusick data[4-i] = hold; 57641480Smckusick } 57741480Smckusick break; 57841480Smckusick 57941480Smckusick case EFTRT: 58041480Smckusick for (i = 0; i < 4; i++) { 58141480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF) + i, 58241480Smckusick NULL, 0, &hold); 58341480Smckusick data[i] = hold; 58441480Smckusick } 58541480Smckusick break; 58641480Smckusick 58741480Smckusick case EFTRLC: 58841480Smckusick case EFTRCC: 58941480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, &hold); 59041480Smckusick *data = hold; 59141480Smckusick break; 59241480Smckusick 59341480Smckusick case EFTSRPG: 59441480Smckusick case EFTSRD: 59541480Smckusick case EFTSRR: 59641480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), data, 1, NULL); 59741480Smckusick break; 59841480Smckusick 59941480Smckusick case EFTSBI: 60053923Shibler #ifdef hp800 60153923Shibler /* XXX big magic */ 60253923Shibler hold = 7 - (*(u_char *)data >> 5); 60353923Shibler *(int *)data = 0x84069008 | (hold << 8); 60453923Shibler send_hil_cmd(hilp->hl_addr, HIL_STARTCMD, data, 4, NULL); 60553923Shibler send_hil_cmd(hilp->hl_addr, 0xC4, NULL, 0, NULL); 60653923Shibler break; 60753923Shibler #else 60841480Smckusick hilbeep(hilp, (struct _hilbell *)data); 60953923Shibler #endif 61041480Smckusick break; 61141480Smckusick 61241480Smckusick case FIONBIO: 61341480Smckusick dptr = &hilp->hl_device[device]; 61441480Smckusick if (*(int *)data) 61541480Smckusick dptr->hd_flags |= HIL_NOBLOCK; 61641480Smckusick else 61741480Smckusick dptr->hd_flags &= ~HIL_NOBLOCK; 61841480Smckusick break; 61941480Smckusick 62041480Smckusick case FIOASYNC: 62141480Smckusick break; 62241480Smckusick 62341480Smckusick default: 62441480Smckusick hilp->hl_cmddev = 0; 62541480Smckusick return(EINVAL); 62641480Smckusick } 62741480Smckusick hilp->hl_cmddev = 0; 62841480Smckusick return(0); 62941480Smckusick } 63041480Smckusick #endif 63141480Smckusick 63241480Smckusick /* ARGSUSED */ 63341480Smckusick hilmap(dev, off, prot) 63441480Smckusick dev_t dev; 63541480Smckusick register int off; 63641480Smckusick { 63741480Smckusick } 63841480Smckusick 63941480Smckusick /*ARGSUSED*/ 64049132Skarels hilselect(dev, rw, p) 64141480Smckusick dev_t dev; 64249132Skarels struct proc *p; 64341480Smckusick { 64453923Shibler register struct hilloop *hilp = &hilloop[HILLOOP(dev)]; 64541480Smckusick register struct hilloopdev *dptr; 64641480Smckusick register struct hiliqueue *qp; 64741480Smckusick register int mask; 64841480Smckusick int s, device; 64941480Smckusick 65041480Smckusick if (rw == FWRITE) 65141480Smckusick return (1); 65241480Smckusick device = HILUNIT(dev); 65341480Smckusick 65441480Smckusick /* 65541480Smckusick * Read interface. 65641480Smckusick * Return 1 if there is something in the queue, 0 ow. 65741480Smckusick */ 65841480Smckusick dptr = &hilp->hl_device[device]; 65941480Smckusick if (dptr->hd_flags & HIL_READIN) { 66041480Smckusick s = splhil(); 66141480Smckusick if (dptr->hd_queue.c_cc) { 66241480Smckusick splx(s); 66341480Smckusick return (1); 66441480Smckusick } 66552533Smckusick selrecord(p, &dptr->hd_selr); 66641480Smckusick splx(s); 66741480Smckusick return (0); 66841480Smckusick } 66941480Smckusick 67041480Smckusick /* 67141480Smckusick * Make sure device is alive and real (or the loop device). 67241480Smckusick * Note that we do not do this for the read interface. 67341480Smckusick * This is primarily to be consistant with HP-UX. 67441480Smckusick */ 67541480Smckusick if (device && (dptr->hd_flags & (HIL_ALIVE|HIL_PSEUDO)) != HIL_ALIVE) 67641480Smckusick return (1); 67741480Smckusick 67841480Smckusick /* 67941480Smckusick * Select on loop device is special. 68041480Smckusick * Check to see if there are any data for any loop device 68141480Smckusick * provided it is associated with a queue belonging to this user. 68241480Smckusick */ 68341480Smckusick if (device == 0) 68441480Smckusick mask = -1; 68541480Smckusick else 68641480Smckusick mask = hildevmask(device); 68741480Smckusick /* 68841480Smckusick * Must check everybody with interrupts blocked to prevent races. 68941480Smckusick */ 69041480Smckusick s = splhil(); 69141480Smckusick for (qp = hilp->hl_queue; qp < &hilp->hl_queue[NHILQ]; qp++) 69243316Smckusick if (qp->hq_procp == p && (mask & qp->hq_devmask) && 69341480Smckusick qp->hq_eventqueue->hil_evqueue.head != 69441480Smckusick qp->hq_eventqueue->hil_evqueue.tail) { 69541480Smckusick splx(s); 69641480Smckusick return (1); 69741480Smckusick } 69841480Smckusick 69952533Smckusick selrecord(p, &dptr->hd_selr); 70041480Smckusick splx(s); 70141480Smckusick return (0); 70241480Smckusick } 70341480Smckusick 70453923Shibler /*ARGSUSED*/ 70553923Shibler hilint(unit) 70641480Smckusick { 70753923Shibler #ifdef hp300 70853923Shibler struct hilloop *hilp = &hilloop[0]; /* XXX how do we know on 300? */ 70953923Shibler #else 71053923Shibler struct hilloop *hilp = &hilloop[unit]; 71153923Shibler #endif 71241480Smckusick register struct hil_dev *hildevice = hilp->hl_addr; 71341480Smckusick u_char c, stat; 71441480Smckusick 71553923Shibler stat = READHILSTAT(hildevice); 71653923Shibler c = READHILDATA(hildevice); /* clears interrupt */ 71753923Shibler hil_process_int(hilp, stat, c); 71841480Smckusick } 71941480Smckusick 72041480Smckusick #include "ite.h" 72141480Smckusick 72253923Shibler hil_process_int(hilp, stat, c) 72353923Shibler register struct hilloop *hilp; 72441480Smckusick register u_char stat, c; 72541480Smckusick { 72641480Smckusick #ifdef DEBUG 72741480Smckusick if (hildebug & HDB_EVENTS) 72841480Smckusick printf("hilint: %x %x\n", stat, c); 72941480Smckusick #endif 73041480Smckusick 73141480Smckusick /* the shift enables the compiler to generate a jump table */ 73241480Smckusick switch ((stat>>HIL_SSHIFT) & HIL_SMASK) { 73341480Smckusick 73441480Smckusick #if NITE > 0 73541480Smckusick case HIL_KEY: 73641480Smckusick case HIL_SHIFT: 73741480Smckusick case HIL_CTRL: 73841480Smckusick case HIL_CTRLSHIFT: 73941480Smckusick itefilter(stat, c); 74041480Smckusick return; 74141480Smckusick #endif 74241480Smckusick 74341480Smckusick case HIL_STATUS: /* The status info. */ 74441480Smckusick if (c & HIL_ERROR) { 74541480Smckusick hilp->hl_cmddone = TRUE; 74641480Smckusick if (c == HIL_RECONFIG) 74741480Smckusick hilconfig(hilp); 74841480Smckusick break; 74941480Smckusick } 75041480Smckusick if (c & HIL_COMMAND) { 75141480Smckusick if (c & HIL_POLLDATA) /* End of data */ 75241480Smckusick hilevent(hilp); 75341480Smckusick else /* End of command */ 75441480Smckusick hilp->hl_cmdending = TRUE; 75541480Smckusick hilp->hl_actdev = 0; 75641480Smckusick } else { 75741480Smckusick if (c & HIL_POLLDATA) { /* Start of polled data */ 75841480Smckusick if (hilp->hl_actdev != 0) 75941480Smckusick hilevent(hilp); 76041480Smckusick hilp->hl_actdev = (c & HIL_DEVMASK); 76141480Smckusick hilp->hl_pollbp = hilp->hl_pollbuf; 76241480Smckusick } else { /* Start of command */ 76341480Smckusick if (hilp->hl_cmddev == (c & HIL_DEVMASK)) { 76441480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 76541480Smckusick hilp->hl_actdev = 0; 76641480Smckusick } 76741480Smckusick } 76841480Smckusick } 76941480Smckusick return; 77041480Smckusick 77141480Smckusick case HIL_DATA: 77241480Smckusick if (hilp->hl_actdev != 0) /* Collecting poll data */ 77341480Smckusick *hilp->hl_pollbp++ = c; 77441480Smckusick else if (hilp->hl_cmddev != 0) /* Collecting cmd data */ 77541480Smckusick if (hilp->hl_cmdending) { 77641480Smckusick hilp->hl_cmddone = TRUE; 77741480Smckusick hilp->hl_cmdending = FALSE; 77841480Smckusick } else 77941480Smckusick *hilp->hl_cmdbp++ = c; 78041480Smckusick return; 78141480Smckusick 78241480Smckusick case 0: /* force full jump table */ 78341480Smckusick default: 78441480Smckusick return; 78541480Smckusick } 78641480Smckusick } 78741480Smckusick 78841480Smckusick #if defined(DEBUG) && !defined(PANICBUTTON) 78941480Smckusick #define PANICBUTTON 79041480Smckusick #endif 79141480Smckusick 79241480Smckusick /* 79341480Smckusick * Optimized macro to compute: 79441480Smckusick * eq->head == (eq->tail + 1) % eq->size 79541480Smckusick * i.e. has tail caught up with head. We do this because 32 bit long 79641480Smckusick * remaidering is expensive (a function call with our compiler). 79741480Smckusick */ 79841480Smckusick #define HQFULL(eq) (((eq)->head?(eq)->head:(eq)->size) == (eq)->tail+1) 79941480Smckusick #define HQVALID(eq) \ 80041480Smckusick ((eq)->size == HEVQSIZE && (eq)->tail >= 0 && (eq)->tail < HEVQSIZE) 80141480Smckusick 80241480Smckusick hilevent(hilp) 80341480Smckusick struct hilloop *hilp; 80441480Smckusick { 80541480Smckusick register struct hilloopdev *dptr = &hilp->hl_device[hilp->hl_actdev]; 80641480Smckusick register int len, mask, qnum; 80741480Smckusick register u_char *cp, *pp; 80841480Smckusick register HILQ *hq; 80941480Smckusick struct timeval ourtime; 81041480Smckusick hil_packet *proto; 81141480Smckusick int s, len0; 81241480Smckusick long tenths; 81341480Smckusick 81441480Smckusick #ifdef PANICBUTTON 81541480Smckusick static int first; 81641480Smckusick extern int panicbutton; 81741480Smckusick 81841480Smckusick cp = hilp->hl_pollbuf; 81941480Smckusick if (panicbutton && (*cp & HIL_KBDDATA)) { 82041480Smckusick if (*++cp == 0x4E) 82141480Smckusick first = 1; 82241480Smckusick else if (first && *cp == 0x46 && !panicstr) 82341480Smckusick panic("are we having fun yet?"); 82441480Smckusick else 82541480Smckusick first = 0; 82641480Smckusick } 82741480Smckusick #endif 82841480Smckusick #ifdef DEBUG 82941480Smckusick if (hildebug & HDB_EVENTS) { 83041480Smckusick printf("hilevent: dev %d pollbuf: ", hilp->hl_actdev); 83141480Smckusick printhilpollbuf(hilp); 83241480Smckusick printf("\n"); 83341480Smckusick } 83441480Smckusick #endif 83541480Smckusick 83641480Smckusick /* 83741480Smckusick * Note that HIL_READIN effectively "shuts off" any queues 83841480Smckusick * that may have been in use at the time of an HILIOCHPUX call. 83941480Smckusick */ 84041480Smckusick if (dptr->hd_flags & HIL_READIN) { 84141480Smckusick hpuxhilevent(hilp, dptr); 84241480Smckusick return; 84341480Smckusick } 84441480Smckusick 84541480Smckusick /* 84641480Smckusick * If this device isn't on any queue or there are no data 84741480Smckusick * in the packet (can this happen?) do nothing. 84841480Smckusick */ 84941480Smckusick if (dptr->hd_qmask == 0 || 85041480Smckusick (len0 = hilp->hl_pollbp - hilp->hl_pollbuf) <= 0) 85141480Smckusick return; 85241480Smckusick 85341480Smckusick /* 85441480Smckusick * Everybody gets the same time stamp 85541480Smckusick */ 85641480Smckusick s = splclock(); 85741480Smckusick ourtime = time; 85841480Smckusick splx(s); 85941480Smckusick tenths = (ourtime.tv_sec * 100) + (ourtime.tv_usec / 10000); 86041480Smckusick 86141480Smckusick proto = NULL; 86241480Smckusick mask = dptr->hd_qmask; 86341480Smckusick for (qnum = 0; mask; qnum++) { 86441480Smckusick if ((mask & hilqmask(qnum)) == 0) 86541480Smckusick continue; 86641480Smckusick mask &= ~hilqmask(qnum); 86741480Smckusick hq = hilp->hl_queue[qnum].hq_eventqueue; 86841480Smckusick 86941480Smckusick /* 87041480Smckusick * Ensure that queue fields that we rely on are valid 87141480Smckusick * and that there is space in the queue. If either 87241480Smckusick * test fails, we just skip this queue. 87341480Smckusick */ 87441480Smckusick if (!HQVALID(&hq->hil_evqueue) || HQFULL(&hq->hil_evqueue)) 87541480Smckusick continue; 87641480Smckusick 87741480Smckusick /* 87841480Smckusick * Copy data to queue. 87941480Smckusick * If this is the first queue we construct the packet 88041480Smckusick * with length, timestamp and poll buffer data. 88141480Smckusick * For second and sucessive packets we just duplicate 88241480Smckusick * the first packet. 88341480Smckusick */ 88441480Smckusick pp = (u_char *) &hq->hil_event[hq->hil_evqueue.tail]; 88541480Smckusick if (proto == NULL) { 88641480Smckusick proto = (hil_packet *)pp; 88741480Smckusick cp = hilp->hl_pollbuf; 88841480Smckusick len = len0; 88941480Smckusick *pp++ = len + 6; 89041480Smckusick *pp++ = hilp->hl_actdev; 89141480Smckusick *(long *)pp = tenths; 89241480Smckusick pp += sizeof(long); 89341480Smckusick do *pp++ = *cp++; while (--len); 89441480Smckusick } else 89541480Smckusick *(hil_packet *)pp = *proto; 89641480Smckusick 89741480Smckusick if (++hq->hil_evqueue.tail == hq->hil_evqueue.size) 89841480Smckusick hq->hil_evqueue.tail = 0; 89941480Smckusick } 90041480Smckusick 90141480Smckusick /* 90241480Smckusick * Wake up anyone selecting on this device or the loop itself 90341480Smckusick */ 90452533Smckusick selwakeup(&dptr->hd_selr); 90541480Smckusick dptr = &hilp->hl_device[HILLOOPDEV]; 90652533Smckusick selwakeup(&dptr->hd_selr); 90741480Smckusick } 90841480Smckusick 90941480Smckusick #undef HQFULL 91041480Smckusick 91141480Smckusick hpuxhilevent(hilp, dptr) 91241480Smckusick register struct hilloop *hilp; 91341480Smckusick register struct hilloopdev *dptr; 91441480Smckusick { 91541480Smckusick register int len; 91641480Smckusick struct timeval ourtime; 91741480Smckusick long tstamp; 91841480Smckusick int s; 91941480Smckusick 92041480Smckusick /* 92141480Smckusick * Everybody gets the same time stamp 92241480Smckusick */ 92341480Smckusick s = splclock(); 92441480Smckusick ourtime = time; 92541480Smckusick splx(s); 92641480Smckusick tstamp = (ourtime.tv_sec * 100) + (ourtime.tv_usec / 10000); 92741480Smckusick 92841480Smckusick /* 92941480Smckusick * Each packet that goes into the buffer must be preceded by the 93041480Smckusick * number of bytes in the packet, and the timestamp of the packet. 93141480Smckusick * This adds 5 bytes to the packet size. Make sure there is enough 93241480Smckusick * room in the buffer for it, and if not, toss the packet. 93341480Smckusick */ 93441480Smckusick len = hilp->hl_pollbp - hilp->hl_pollbuf; 93541480Smckusick if (dptr->hd_queue.c_cc <= (HILMAXCLIST - (len+5))) { 93641480Smckusick putc(len+5, &dptr->hd_queue); 93741480Smckusick (void) b_to_q((char *)&tstamp, sizeof tstamp, &dptr->hd_queue); 93841480Smckusick (void) b_to_q((char *)hilp->hl_pollbuf, len, &dptr->hd_queue); 93941480Smckusick } 94041480Smckusick 94141480Smckusick /* 94241480Smckusick * Wake up any one blocked on a read or select 94341480Smckusick */ 94441480Smckusick if (dptr->hd_flags & HIL_ASLEEP) { 94541480Smckusick dptr->hd_flags &= ~HIL_ASLEEP; 94641480Smckusick wakeup((caddr_t)dptr); 94741480Smckusick } 94852533Smckusick selwakeup(&dptr->hd_selr); 94941480Smckusick } 95041480Smckusick 95141480Smckusick /* 95241480Smckusick * Shared queue manipulation routines 95341480Smckusick */ 95441480Smckusick 95553923Shibler hilqalloc(hilp, qip) 95653923Shibler register struct hilloop *hilp; 95741480Smckusick struct hilqinfo *qip; 95841480Smckusick { 95949132Skarels struct proc *p = curproc; /* XXX */ 96041480Smckusick 96141480Smckusick #ifdef DEBUG 96241480Smckusick if (hildebug & HDB_FOLLOW) 96345750Smckusick printf("hilqalloc(%d): addr %x\n", p->p_pid, qip->addr); 96441480Smckusick #endif 96541480Smckusick return(EINVAL); 96641480Smckusick } 96741480Smckusick 96853923Shibler hilqfree(hilp, qnum) 96941480Smckusick register int qnum; 97041480Smckusick { 97149132Skarels struct proc *p = curproc; /* XXX */ 97241480Smckusick 97341480Smckusick #ifdef DEBUG 97441480Smckusick if (hildebug & HDB_FOLLOW) 97545750Smckusick printf("hilqfree(%d): qnum %d\n", p->p_pid, qnum); 97641480Smckusick #endif 97741480Smckusick return(EINVAL); 97841480Smckusick } 97941480Smckusick 98053923Shibler hilqmap(hilp, qnum, device) 98153923Shibler register struct hilloop *hilp; 98241480Smckusick register int qnum, device; 98341480Smckusick { 98449132Skarels struct proc *p = curproc; /* XXX */ 98541480Smckusick register struct hilloopdev *dptr = &hilp->hl_device[device]; 98641480Smckusick int s; 98741480Smckusick 98841480Smckusick #ifdef DEBUG 98941480Smckusick if (hildebug & HDB_FOLLOW) 99041480Smckusick printf("hilqmap(%d): qnum %d device %x\n", 99143316Smckusick p->p_pid, qnum, device); 99241480Smckusick #endif 99343316Smckusick if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p) 99441480Smckusick return(EINVAL); 99541480Smckusick if ((dptr->hd_flags & HIL_QUEUEIN) == 0) 99641480Smckusick return(EINVAL); 99749132Skarels if (dptr->hd_qmask && p->p_ucred->cr_uid && 99849132Skarels p->p_ucred->cr_uid != dptr->hd_uid) 99941480Smckusick return(EPERM); 100041480Smckusick 100141480Smckusick hilp->hl_queue[qnum].hq_devmask |= hildevmask(device); 100241480Smckusick if (dptr->hd_qmask == 0) 100349132Skarels dptr->hd_uid = p->p_ucred->cr_uid; 100441480Smckusick s = splhil(); 100541480Smckusick dptr->hd_qmask |= hilqmask(qnum); 100641480Smckusick splx(s); 100741480Smckusick #ifdef DEBUG 100841480Smckusick if (hildebug & HDB_MASK) 100941480Smckusick printf("hilqmap(%d): devmask %x qmask %x\n", 101043316Smckusick p->p_pid, hilp->hl_queue[qnum].hq_devmask, 101141480Smckusick dptr->hd_qmask); 101241480Smckusick #endif 101341480Smckusick return(0); 101441480Smckusick } 101541480Smckusick 101653923Shibler hilqunmap(hilp, qnum, device) 101753923Shibler register struct hilloop *hilp; 101841480Smckusick register int qnum, device; 101941480Smckusick { 102049132Skarels struct proc *p = curproc; /* XXX */ 102141480Smckusick int s; 102241480Smckusick 102341480Smckusick #ifdef DEBUG 102441480Smckusick if (hildebug & HDB_FOLLOW) 102541480Smckusick printf("hilqunmap(%d): qnum %d device %x\n", 102643316Smckusick p->p_pid, qnum, device); 102741480Smckusick #endif 102841480Smckusick 102943316Smckusick if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p) 103041480Smckusick return(EINVAL); 103141480Smckusick 103241480Smckusick hilp->hl_queue[qnum].hq_devmask &= ~hildevmask(device); 103341480Smckusick s = splhil(); 103441480Smckusick hilp->hl_device[device].hd_qmask &= ~hilqmask(qnum); 103541480Smckusick splx(s); 103641480Smckusick #ifdef DEBUG 103741480Smckusick if (hildebug & HDB_MASK) 103841480Smckusick printf("hilqunmap(%d): devmask %x qmask %x\n", 103943316Smckusick p->p_pid, hilp->hl_queue[qnum].hq_devmask, 104041480Smckusick hilp->hl_device[device].hd_qmask); 104141480Smckusick #endif 104241480Smckusick return(0); 104341480Smckusick } 104441480Smckusick 104541480Smckusick /* 104641480Smckusick * Cooked keyboard functions for ite driver. 104741480Smckusick * There is only one "cooked" ITE keyboard (the first keyboard found) 104841480Smckusick * per loop. There may be other keyboards, but they will always be "raw". 104941480Smckusick */ 105041480Smckusick 105153923Shibler kbdbell(unit) 105253923Shibler int unit; 105341480Smckusick { 105453923Shibler struct hilloop *hilp = &hilloop[unit]; 105541480Smckusick 105641480Smckusick hilbeep(hilp, &default_bell); 105741480Smckusick } 105841480Smckusick 105953923Shibler kbdenable(unit) 106053923Shibler int unit; 106141480Smckusick { 106253923Shibler struct hilloop *hilp = &hilloop[unit]; 106341480Smckusick register struct hil_dev *hildevice = hilp->hl_addr; 106441480Smckusick char db; 106541480Smckusick 106641480Smckusick /* Set the autorepeat rate register */ 106741480Smckusick db = ar_format(KBD_ARR); 106841480Smckusick send_hil_cmd(hildevice, HIL_SETARR, &db, 1, NULL); 106941480Smckusick 107041480Smckusick /* Set the autorepeat delay register */ 107141480Smckusick db = ar_format(KBD_ARD); 107241480Smckusick send_hil_cmd(hildevice, HIL_SETARD, &db, 1, NULL); 107341480Smckusick 107441480Smckusick /* Enable interrupts */ 107541480Smckusick send_hil_cmd(hildevice, HIL_INTON, NULL, 0, NULL); 107641480Smckusick } 107741480Smckusick 107853923Shibler kbddisable(unit) 107953923Shibler int unit; 108041480Smckusick { 108141480Smckusick } 108241480Smckusick 108341480Smckusick /* 108441480Smckusick * XXX: read keyboard directly and return code. 108541480Smckusick * Used by console getchar routine. Could really screw up anybody 108641480Smckusick * reading from the keyboard in the normal, interrupt driven fashion. 108741480Smckusick */ 108853923Shibler kbdgetc(unit, statp) 108953923Shibler int unit, *statp; 109041480Smckusick { 109153923Shibler struct hilloop *hilp = &hilloop[unit]; 109241480Smckusick register struct hil_dev *hildevice = hilp->hl_addr; 109341480Smckusick register int c, stat; 109441480Smckusick int s; 109541480Smckusick 109641480Smckusick s = splhil(); 109753923Shibler while (((stat = READHILSTAT(hildevice)) & HIL_DATA_RDY) == 0) 109841480Smckusick ; 109953923Shibler c = READHILDATA(hildevice); 110041480Smckusick splx(s); 110141480Smckusick *statp = stat; 110241480Smckusick return(c); 110341480Smckusick } 110441480Smckusick 110541480Smckusick /* 110641480Smckusick * Recoginize and clear keyboard generated NMIs. 110741480Smckusick * Returns 1 if it was ours, 0 otherwise. Note that we cannot use 110841480Smckusick * send_hil_cmd() to issue the clear NMI command as that would actually 110941480Smckusick * lower the priority to splimp() and it doesn't wait for the completion 111041480Smckusick * of the command. Either of these conditions could result in the 111141480Smckusick * interrupt reoccuring. Note that we issue the CNMT command twice. 111241480Smckusick * This seems to be needed, once is not always enough!?! 111341480Smckusick */ 111453923Shibler kbdnmi(unit) 111553923Shibler int unit; 111641480Smckusick { 111753923Shibler #ifdef hp300 111853923Shibler struct hilloop *hilp = &hilloop[0]; /* XXX how do we know on 300? */ 111953923Shibler #else 112053923Shibler struct hilloop *hilp = &hilloop[unit]; 112153923Shibler #endif 112253923Shibler #ifdef hp300 112341480Smckusick if ((*KBDNMISTAT & KBDNMI) == 0) 112441480Smckusick return(0); 112553923Shibler #endif 112641480Smckusick HILWAIT(hilp->hl_addr); 112753923Shibler WRITEHILCMD(hilp->hl_addr, HIL_CNMT); 112841480Smckusick HILWAIT(hilp->hl_addr); 112953923Shibler WRITEHILCMD(hilp->hl_addr, HIL_CNMT); 113041480Smckusick HILWAIT(hilp->hl_addr); 113141480Smckusick return(1); 113241480Smckusick } 113341480Smckusick 113441480Smckusick #define HILSECURITY 0x33 113541480Smckusick #define HILIDENTIFY 0x03 113641480Smckusick #define HILSCBIT 0x04 113741480Smckusick 113841480Smckusick /* 113941480Smckusick * Called at boot time to print out info about interesting devices 114041480Smckusick */ 114153923Shibler hilinfo(unit) 114253923Shibler int unit; 114341480Smckusick { 114453923Shibler register struct hilloop *hilp = &hilloop[unit]; 114541480Smckusick register int id, len; 114641480Smckusick register struct kbdmap *km; 114741480Smckusick 114841480Smckusick /* 114941480Smckusick * Keyboard info. 115041480Smckusick */ 115141480Smckusick if (hilp->hl_kbddev) { 115241480Smckusick printf("hil%d: ", hilp->hl_kbddev); 115341480Smckusick for (km = kbd_map; km->kbd_code; km++) 115441480Smckusick if (km->kbd_code == hilp->hl_kbdlang) { 115541480Smckusick printf("%s ", km->kbd_desc); 115641480Smckusick break; 115741480Smckusick } 115841480Smckusick printf("keyboard\n"); 115941480Smckusick } 116041480Smckusick /* 116141480Smckusick * ID module. 116241480Smckusick * Attempt to locate the first ID module and print out its 116341480Smckusick * security code. Is this a good idea?? 116441480Smckusick */ 116541480Smckusick id = hiliddev(hilp); 116641480Smckusick if (id) { 116741480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 116841480Smckusick hilp->hl_cmddev = id; 116941480Smckusick send_hildev_cmd(hilp, id, HILSECURITY); 117041480Smckusick len = hilp->hl_cmdbp - hilp->hl_cmdbuf; 117141480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 117241480Smckusick hilp->hl_cmddev = 0; 117341480Smckusick printf("hil%d: security code", id); 117441480Smckusick for (id = 0; id < len; id++) 117541480Smckusick printf(" %x", hilp->hl_cmdbuf[id]); 117641480Smckusick while (id++ < 16) 117741480Smckusick printf(" 0"); 117841480Smckusick printf("\n"); 117941480Smckusick } 118041480Smckusick } 118141480Smckusick 118241480Smckusick #define HILAR1 0x3E 118341480Smckusick #define HILAR2 0x3F 118441480Smckusick 118541480Smckusick /* 118641480Smckusick * Called after the loop has reconfigured. Here we need to: 118741480Smckusick * - determine how many devices are on the loop 118841480Smckusick * (some may have been added or removed) 118941480Smckusick * - locate the ITE keyboard (if any) and ensure 119041480Smckusick * that it is in the proper state (raw or cooked) 119141480Smckusick * and is set to use the proper language mapping table 119241480Smckusick * - ensure all other keyboards are raw 119341480Smckusick * Note that our device state is now potentially invalid as 119441480Smckusick * devices may no longer be where they were. What we should 119541480Smckusick * do here is either track where the devices went and move 119641480Smckusick * state around accordingly or, more simply, just mark all 119741480Smckusick * devices as HIL_DERROR and don't allow any further use until 119841480Smckusick * they are closed. This is a little too brutal for my tastes, 119941480Smckusick * we prefer to just assume people won't move things around. 120041480Smckusick */ 120141480Smckusick hilconfig(hilp) 120241480Smckusick register struct hilloop *hilp; 120341480Smckusick { 120441480Smckusick u_char db; 120541480Smckusick int s; 120641480Smckusick 120741480Smckusick s = splhil(); 120841480Smckusick #ifdef DEBUG 120941480Smckusick if (hildebug & HDB_CONFIG) { 121041480Smckusick printf("hilconfig: reconfigured: "); 121141480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READLPSTAT, NULL, 0, &db); 121241480Smckusick printf("LPSTAT %x, ", db); 121341480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READLPCTRL, NULL, 0, &db); 121441480Smckusick printf("LPCTRL %x, ", db); 121541480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READKBDSADR, NULL, 0, &db); 121641480Smckusick printf("KBDSADR %x\n", db); 121741480Smckusick hilreport(hilp); 121841480Smckusick } 121941480Smckusick #endif 122041480Smckusick /* 122141480Smckusick * Determine how many devices are on the loop. 122241480Smckusick * Mark those as alive and real, all others as dead. 122341480Smckusick */ 122441480Smckusick db = 0; 122541480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READLPSTAT, NULL, 0, &db); 122641480Smckusick hilp->hl_maxdev = db & LPS_DEVMASK; 122753923Shibler #ifdef DEBUG 122853923Shibler if (hildebug & HDB_CONFIG) 122953923Shibler printf("hilconfig: %d devices found\n", hilp->hl_maxdev); 123053923Shibler #endif 123141480Smckusick for (db = 1; db < NHILD; db++) { 123241480Smckusick if (db <= hilp->hl_maxdev) 123341480Smckusick hilp->hl_device[db].hd_flags |= HIL_ALIVE; 123441480Smckusick else 123541480Smckusick hilp->hl_device[db].hd_flags &= ~HIL_ALIVE; 123641480Smckusick hilp->hl_device[db].hd_flags &= ~HIL_PSEUDO; 123741480Smckusick } 123841480Smckusick #ifdef DEBUG 123941480Smckusick if (hildebug & (HDB_CONFIG|HDB_KEYBOARD)) 124041480Smckusick printf("hilconfig: max device %d\n", hilp->hl_maxdev); 124141480Smckusick #endif 124241480Smckusick if (hilp->hl_maxdev == 0) { 124341480Smckusick hilp->hl_kbddev = 0; 124441480Smckusick splx(s); 124541480Smckusick return; 124641480Smckusick } 124741480Smckusick /* 124841480Smckusick * Find out where the keyboards are and record the ITE keyboard 124941480Smckusick * (first one found). If no keyboards found, we are all done. 125041480Smckusick */ 125141480Smckusick db = 0; 125241480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READKBDSADR, NULL, 0, &db); 125341480Smckusick #ifdef DEBUG 125441480Smckusick if (hildebug & HDB_KEYBOARD) 125541480Smckusick printf("hilconfig: keyboard: KBDSADR %x, old %d, new %d\n", 125641480Smckusick db, hilp->hl_kbddev, ffs((int)db)); 125741480Smckusick #endif 125841480Smckusick hilp->hl_kbddev = ffs((int)db); 125941480Smckusick if (hilp->hl_kbddev == 0) { 126041480Smckusick splx(s); 126141480Smckusick return; 126241480Smckusick } 126341480Smckusick /* 126441480Smckusick * Determine if the keyboard should be cooked or raw and configure it. 126541480Smckusick */ 126641480Smckusick db = (hilp->hl_kbdflags & KBD_RAW) ? 0 : 1 << (hilp->hl_kbddev - 1); 126741480Smckusick send_hil_cmd(hilp->hl_addr, HIL_WRITEKBDSADR, &db, 1, NULL); 126841480Smckusick /* 126941480Smckusick * Re-enable autorepeat in raw mode, cooked mode AR is not affected. 127041480Smckusick */ 127141480Smckusick if (hilp->hl_kbdflags & (KBD_AR1|KBD_AR2)) { 127241480Smckusick db = (hilp->hl_kbdflags & KBD_AR1) ? HILAR1 : HILAR2; 127341480Smckusick hilp->hl_cmddev = hilp->hl_kbddev; 127441480Smckusick send_hildev_cmd(hilp, hilp->hl_kbddev, db); 127541480Smckusick hilp->hl_cmddev = 0; 127641480Smckusick } 127741480Smckusick /* 127841480Smckusick * Determine the keyboard language configuration, but don't 127941480Smckusick * override a user-specified setting. 128041480Smckusick */ 128141480Smckusick db = 0; 128241480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READKBDLANG, NULL, 0, &db); 128341480Smckusick #ifdef DEBUG 128441480Smckusick if (hildebug & HDB_KEYBOARD) 128541480Smckusick printf("hilconfig: language: old %x new %x\n", 128641480Smckusick hilp->hl_kbdlang, db); 128741480Smckusick #endif 128841480Smckusick if (hilp->hl_kbdlang != KBD_SPECIAL) { 128941480Smckusick struct kbdmap *km; 129041480Smckusick 129141480Smckusick for (km = kbd_map; km->kbd_code; km++) 129241480Smckusick if (km->kbd_code == db) { 129341480Smckusick hilp->hl_kbdlang = db; 129441480Smckusick /* XXX */ 129541480Smckusick kbd_keymap = km->kbd_keymap; 129641480Smckusick kbd_shiftmap = km->kbd_shiftmap; 129741480Smckusick kbd_ctrlmap = km->kbd_ctrlmap; 129841480Smckusick kbd_ctrlshiftmap = km->kbd_ctrlshiftmap; 129941480Smckusick kbd_stringmap = km->kbd_stringmap; 130041480Smckusick } 130141480Smckusick } 130241480Smckusick splx(s); 130341480Smckusick } 130441480Smckusick 130541480Smckusick hilreset(hilp) 130641480Smckusick struct hilloop *hilp; 130741480Smckusick { 130841480Smckusick register struct hil_dev *hildevice = hilp->hl_addr; 130941480Smckusick u_char db; 131041480Smckusick 131153923Shibler #ifdef DEBUG 131253923Shibler if (hildebug & HDB_FOLLOW) 131353923Shibler printf("hilreset(%x)\n", hilp); 131453923Shibler #endif 131541480Smckusick /* 131641480Smckusick * Initialize the loop: reconfigure, don't report errors, 131741480Smckusick * cook keyboards, and enable autopolling. 131841480Smckusick */ 131941480Smckusick db = LPC_RECONF | LPC_KBDCOOK | LPC_NOERROR | LPC_AUTOPOLL; 132041480Smckusick send_hil_cmd(hildevice, HIL_WRITELPCTRL, &db, 1, NULL); 132141480Smckusick /* 132241480Smckusick * Delay one second for reconfiguration and then read the the 132341480Smckusick * data register to clear the interrupt (if the loop reconfigured). 132441480Smckusick */ 132541480Smckusick DELAY(1000000); 132653923Shibler if (READHILSTAT(hildevice) & HIL_DATA_RDY) 132753923Shibler db = READHILDATA(hildevice); 132841480Smckusick /* 132941480Smckusick * The HIL loop may have reconfigured. If so we proceed on, 133041480Smckusick * if not we loop until a successful reconfiguration is reported 133141480Smckusick * back to us. The HIL loop will continue to attempt forever. 133241480Smckusick * Probably not very smart. 133341480Smckusick */ 133441480Smckusick do { 133541480Smckusick send_hil_cmd(hildevice, HIL_READLPSTAT, NULL, 0, &db); 133641480Smckusick } while ((db & (LPS_CONFFAIL|LPS_CONFGOOD)) == 0); 133741480Smckusick /* 133841480Smckusick * At this point, the loop should have reconfigured. 133941480Smckusick * The reconfiguration interrupt has already called hilconfig() 134043411Shibler * so the keyboard has been determined. 134141480Smckusick */ 134241480Smckusick send_hil_cmd(hildevice, HIL_INTON, NULL, 0, NULL); 134341480Smckusick } 134441480Smckusick 134541480Smckusick hilbeep(hilp, bp) 134641480Smckusick struct hilloop *hilp; 134741480Smckusick register struct _hilbell *bp; 134841480Smckusick { 134941480Smckusick u_char buf[2]; 135041480Smckusick 135141480Smckusick buf[0] = ~((bp->duration - 10) / 10); 135241480Smckusick buf[1] = bp->frequency; 135341480Smckusick send_hil_cmd(hilp->hl_addr, HIL_SETTONE, buf, 2, NULL); 135441480Smckusick } 135541480Smckusick 135641480Smckusick /* 135741480Smckusick * Locate and return the address of the first ID module, 0 if none present. 135841480Smckusick */ 135941480Smckusick hiliddev(hilp) 136041480Smckusick register struct hilloop *hilp; 136141480Smckusick { 136241480Smckusick register int i, len; 136341480Smckusick 136441480Smckusick #ifdef DEBUG 136541480Smckusick if (hildebug & HDB_IDMODULE) 136653923Shibler printf("hiliddev(%x): max %d, looking for idmodule...", 136753923Shibler hilp, hilp->hl_maxdev); 136841480Smckusick #endif 136941480Smckusick for (i = 1; i <= hilp->hl_maxdev; i++) { 137041480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 137141480Smckusick hilp->hl_cmddev = i; 137241480Smckusick send_hildev_cmd(hilp, i, HILIDENTIFY); 137341480Smckusick /* 137441480Smckusick * XXX: the final condition checks to ensure that the 137541480Smckusick * device ID byte is in the range of the ID module (0x30-0x3F) 137641480Smckusick */ 137741480Smckusick len = hilp->hl_cmdbp - hilp->hl_cmdbuf; 137841480Smckusick if (len > 1 && (hilp->hl_cmdbuf[1] & HILSCBIT) && 137941480Smckusick (hilp->hl_cmdbuf[0] & 0xF0) == 0x30) { 138041480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 138141480Smckusick hilp->hl_cmddev = i; 138241480Smckusick send_hildev_cmd(hilp, i, HILSECURITY); 138341480Smckusick break; 138441480Smckusick } 138541480Smckusick } 138641480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 138741480Smckusick hilp->hl_cmddev = 0; 138841480Smckusick #ifdef DEBUG 138941480Smckusick if (hildebug & HDB_IDMODULE) 139041480Smckusick if (i <= hilp->hl_maxdev) 139141480Smckusick printf("found at %d\n", i); 139241480Smckusick else 139341480Smckusick printf("not found\n"); 139441480Smckusick #endif 139541480Smckusick return(i <= hilp->hl_maxdev ? i : 0); 139641480Smckusick } 139741480Smckusick 139853923Shibler #ifdef HPUXCOMPAT 139941480Smckusick /* 140053923Shibler * XXX map devno as expected by HP-UX 140153923Shibler */ 140253923Shibler hildevno(dev) 140353923Shibler dev_t dev; 140453923Shibler { 140553923Shibler int newdev; 140653923Shibler 140753923Shibler newdev = 24 << 24; 140853923Shibler #ifdef HILCOMPAT 140953923Shibler /* 141053923Shibler * XXX compat check 141153923Shibler * Don't convert old style specfiles already in correct format 141253923Shibler */ 141353923Shibler if (minor(dev) && (dev & 0xF) == 0) 141453923Shibler newdev |= minor(dev); 141553923Shibler else 141653923Shibler #endif 141753923Shibler newdev |= (HILLOOP(dev) << 8) | (HILUNIT(dev) << 4); 141853923Shibler return(newdev); 141953923Shibler } 142053923Shibler #endif 142153923Shibler 142253923Shibler /* 142341480Smckusick * Low level routines which actually talk to the 8042 chip. 142441480Smckusick */ 142541480Smckusick 142641480Smckusick /* 142741480Smckusick * Send a command to the 8042 with zero or more bytes of data. 142841480Smckusick * If rdata is non-null, wait for and return a byte of data. 142941480Smckusick * We run at splimp() to make the transaction as atomic as 143041480Smckusick * possible without blocking the clock (is this necessary?) 143141480Smckusick */ 143241480Smckusick send_hil_cmd(hildevice, cmd, data, dlen, rdata) 143341480Smckusick register struct hil_dev *hildevice; 143441480Smckusick u_char cmd, *data, dlen; 143541480Smckusick u_char *rdata; 143641480Smckusick { 143741480Smckusick u_char status; 143841480Smckusick int s = splimp(); 143941480Smckusick 144041480Smckusick HILWAIT(hildevice); 144153923Shibler WRITEHILCMD(hildevice, cmd); 144241480Smckusick while (dlen--) { 144341480Smckusick HILWAIT(hildevice); 144453923Shibler WRITEHILDATA(hildevice, *data++); 144541480Smckusick } 144641480Smckusick if (rdata) { 144741480Smckusick do { 144841480Smckusick HILDATAWAIT(hildevice); 144953923Shibler status = READHILSTAT(hildevice); 145053923Shibler *rdata = READHILDATA(hildevice); 145141480Smckusick } while (((status >> HIL_SSHIFT) & HIL_SMASK) != HIL_68K); 145241480Smckusick } 145341480Smckusick splx(s); 145441480Smckusick } 145541480Smckusick 145641480Smckusick /* 145741480Smckusick * Send a command to a device on the loop. 145841480Smckusick * Since only one command can be active on the loop at any time, 145941480Smckusick * we must ensure that we are not interrupted during this process. 146041480Smckusick * Hence we mask interrupts to prevent potential access from most 146141480Smckusick * interrupt routines and turn off auto-polling to disable the 146241480Smckusick * internally generated poll commands. 146341480Smckusick * 146441480Smckusick * splhigh is extremely conservative but insures atomic operation, 146541480Smckusick * splimp (clock only interrupts) seems to be good enough in practice. 146641480Smckusick */ 146741480Smckusick send_hildev_cmd(hilp, device, cmd) 146841480Smckusick register struct hilloop *hilp; 146941480Smckusick char device, cmd; 147041480Smckusick { 147141480Smckusick register struct hil_dev *hildevice = hilp->hl_addr; 147241480Smckusick u_char status, c; 147341480Smckusick int s = splimp(); 147441480Smckusick 147541480Smckusick polloff(hildevice); 147641480Smckusick 147741480Smckusick /* 147841480Smckusick * Transfer the command and device info to the chip 147941480Smckusick */ 148041480Smckusick HILWAIT(hildevice); 148153923Shibler WRITEHILCMD(hildevice, HIL_STARTCMD); 148241480Smckusick HILWAIT(hildevice); 148353923Shibler WRITEHILDATA(hildevice, 8 + device); 148441480Smckusick HILWAIT(hildevice); 148553923Shibler WRITEHILDATA(hildevice, cmd); 148641480Smckusick HILWAIT(hildevice); 148753923Shibler WRITEHILDATA(hildevice, HIL_TIMEOUT); 148841480Smckusick /* 148941480Smckusick * Trigger the command and wait for completion 149041480Smckusick */ 149141480Smckusick HILWAIT(hildevice); 149253923Shibler WRITEHILCMD(hildevice, HIL_TRIGGER); 149341480Smckusick hilp->hl_cmddone = FALSE; 149441480Smckusick do { 149541480Smckusick HILDATAWAIT(hildevice); 149653923Shibler status = READHILSTAT(hildevice); 149753923Shibler c = READHILDATA(hildevice); 149853923Shibler hil_process_int(hilp, status, c); 149941480Smckusick } while (!hilp->hl_cmddone); 150041480Smckusick 150141480Smckusick pollon(hildevice); 150241480Smckusick splx(s); 150341480Smckusick } 150441480Smckusick 150541480Smckusick /* 150641480Smckusick * Turn auto-polling off and on. 150741480Smckusick * Also disables and enable auto-repeat. Why? 150841480Smckusick */ 150941480Smckusick polloff(hildevice) 151041480Smckusick register struct hil_dev *hildevice; 151141480Smckusick { 151241480Smckusick register char db; 151341480Smckusick 151441480Smckusick /* 151541480Smckusick * Turn off auto repeat 151641480Smckusick */ 151741480Smckusick HILWAIT(hildevice); 151853923Shibler WRITEHILCMD(hildevice, HIL_SETARR); 151941480Smckusick HILWAIT(hildevice); 152053923Shibler WRITEHILDATA(hildevice, 0); 152141480Smckusick /* 152241480Smckusick * Turn off auto-polling 152341480Smckusick */ 152441480Smckusick HILWAIT(hildevice); 152553923Shibler WRITEHILCMD(hildevice, HIL_READLPCTRL); 152641480Smckusick HILDATAWAIT(hildevice); 152753923Shibler db = READHILDATA(hildevice); 152841480Smckusick db &= ~LPC_AUTOPOLL; 152941480Smckusick HILWAIT(hildevice); 153053923Shibler WRITEHILCMD(hildevice, HIL_WRITELPCTRL); 153141480Smckusick HILWAIT(hildevice); 153253923Shibler WRITEHILDATA(hildevice, db); 153341480Smckusick /* 153441480Smckusick * Must wait til polling is really stopped 153541480Smckusick */ 153641480Smckusick do { 153741480Smckusick HILWAIT(hildevice); 153853923Shibler WRITEHILCMD(hildevice, HIL_READBUSY); 153941480Smckusick HILDATAWAIT(hildevice); 154053923Shibler db = READHILDATA(hildevice); 154141480Smckusick } while (db & BSY_LOOPBUSY); 154241480Smckusick } 154341480Smckusick 154441480Smckusick pollon(hildevice) 154541480Smckusick register struct hil_dev *hildevice; 154641480Smckusick { 154741480Smckusick register char db; 154841480Smckusick 154941480Smckusick /* 155041480Smckusick * Turn on auto polling 155141480Smckusick */ 155241480Smckusick HILWAIT(hildevice); 155353923Shibler WRITEHILCMD(hildevice, HIL_READLPCTRL); 155441480Smckusick HILDATAWAIT(hildevice); 155553923Shibler db = READHILDATA(hildevice); 155641480Smckusick db |= LPC_AUTOPOLL; 155741480Smckusick HILWAIT(hildevice); 155853923Shibler WRITEHILCMD(hildevice, HIL_WRITELPCTRL); 155941480Smckusick HILWAIT(hildevice); 156053923Shibler WRITEHILDATA(hildevice, db); 156141480Smckusick /* 156241480Smckusick * Turn on auto repeat 156341480Smckusick */ 156441480Smckusick HILWAIT(hildevice); 156553923Shibler WRITEHILCMD(hildevice, HIL_SETARR); 156641480Smckusick HILWAIT(hildevice); 156753923Shibler WRITEHILDATA(hildevice, ar_format(KBD_ARR)); 156841480Smckusick } 156941480Smckusick 157041480Smckusick #ifdef DEBUG 157141480Smckusick printhilpollbuf(hilp) 157241480Smckusick register struct hilloop *hilp; 157341480Smckusick { 157441480Smckusick register u_char *cp; 157541480Smckusick register int i, len; 157641480Smckusick 157741480Smckusick cp = hilp->hl_pollbuf; 157841480Smckusick len = hilp->hl_pollbp - cp; 157941480Smckusick for (i = 0; i < len; i++) 158041480Smckusick printf("%x ", hilp->hl_pollbuf[i]); 158141480Smckusick printf("\n"); 158241480Smckusick } 158341480Smckusick 158441480Smckusick printhilcmdbuf(hilp) 158541480Smckusick register struct hilloop *hilp; 158641480Smckusick { 158741480Smckusick register u_char *cp; 158841480Smckusick register int i, len; 158941480Smckusick 159041480Smckusick cp = hilp->hl_cmdbuf; 159141480Smckusick len = hilp->hl_cmdbp - cp; 159241480Smckusick for (i = 0; i < len; i++) 159341480Smckusick printf("%x ", hilp->hl_cmdbuf[i]); 159441480Smckusick printf("\n"); 159541480Smckusick } 159641480Smckusick 159741480Smckusick hilreport(hilp) 159841480Smckusick register struct hilloop *hilp; 159941480Smckusick { 160041480Smckusick register int i, len; 160141480Smckusick int s = splhil(); 160241480Smckusick 160341480Smckusick for (i = 1; i <= hilp->hl_maxdev; i++) { 160441480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 160541480Smckusick hilp->hl_cmddev = i; 160641480Smckusick send_hildev_cmd(hilp, i, HILIDENTIFY); 160741480Smckusick printf("hil%d: id: ", i); 160841480Smckusick printhilcmdbuf(hilp); 160941480Smckusick len = hilp->hl_cmdbp - hilp->hl_cmdbuf; 161041480Smckusick if (len > 1 && (hilp->hl_cmdbuf[1] & HILSCBIT)) { 161141480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 161241480Smckusick hilp->hl_cmddev = i; 161341480Smckusick send_hildev_cmd(hilp, i, HILSECURITY); 161441480Smckusick printf("hil%d: sc: ", i); 161541480Smckusick printhilcmdbuf(hilp); 161641480Smckusick } 161741480Smckusick } 161841480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 161941480Smckusick hilp->hl_cmddev = 0; 162041480Smckusick splx(s); 162141480Smckusick } 162241480Smckusick #endif 1623