141480Smckusick /* 241480Smckusick * Copyright (c) 1988 University of Utah. 363146Sbostic * Copyright (c) 1990, 1993 463146Sbostic * The Regents of the University of California. 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*65643Sbostic * @(#)hil.c 8.2 (Berkeley) 01/12/94 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 */ 16357309Shibler 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; 201*65643Sbostic int flags, mode; 20252532Skarels struct proc *p; 20341480Smckusick { 20453923Shibler register struct hilloop *hilp = &hilloop[HILLOOP(dev)]; 20541480Smckusick register struct hilloopdev *dptr; 20641480Smckusick register int i; 20741480Smckusick u_char device = HILUNIT(dev); 20841480Smckusick char mask, lpctrl; 20941480Smckusick 21041480Smckusick #ifdef DEBUG 21141480Smckusick if (hildebug & HDB_FOLLOW) 21243316Smckusick printf("hilclose(%d): device %x\n", p->p_pid, device); 21341480Smckusick #endif 21441480Smckusick 21541480Smckusick dptr = &hilp->hl_device[device]; 21641480Smckusick if (device && (dptr->hd_flags & HIL_PSEUDO)) 21741480Smckusick return (0); 21841480Smckusick 21957309Shibler if (p && (p->p_md.md_flags & MDP_HPUX) == 0) { 22041480Smckusick /* 22141480Smckusick * If this is the loop device, 22241480Smckusick * free up all queues belonging to this process. 22341480Smckusick */ 22441480Smckusick if (device == 0) { 22541480Smckusick for (i = 0; i < NHILQ; i++) 22643316Smckusick if (hilp->hl_queue[i].hq_procp == p) 22753923Shibler (void) hilqfree(hilp, i); 22841480Smckusick } else { 22941480Smckusick mask = ~hildevmask(device); 23041480Smckusick (void) splhil(); 23141480Smckusick for (i = 0; i < NHILQ; i++) 23243316Smckusick if (hilp->hl_queue[i].hq_procp == p) { 23341480Smckusick dptr->hd_qmask &= ~hilqmask(i); 23441480Smckusick hilp->hl_queue[i].hq_devmask &= mask; 23541480Smckusick } 23641480Smckusick (void) spl0(); 23741480Smckusick } 23841480Smckusick } 23941480Smckusick /* 24041480Smckusick * Always flush the read buffer 24141480Smckusick */ 24241480Smckusick dptr->hd_flags &= ~(HIL_QUEUEIN|HIL_READIN|HIL_NOBLOCK); 24341480Smckusick ndflush(&dptr->hd_queue, dptr->hd_queue.c_cc); 24441480Smckusick /* 24541480Smckusick * Set keyboard back to cooked mode when closed. 24641480Smckusick */ 24741480Smckusick (void) splhil(); 24841480Smckusick if (device && device == hilp->hl_kbddev) { 24941480Smckusick mask = 1 << (hilp->hl_kbddev - 1); 25041480Smckusick send_hil_cmd(hilp->hl_addr, HIL_WRITEKBDSADR, &mask, 1, NULL); 25141480Smckusick hilp->hl_kbdflags &= ~(KBD_RAW|KBD_AR1|KBD_AR2); 25241480Smckusick /* 25341480Smckusick * XXX: We have had trouble with keyboards remaining raw 25441480Smckusick * after close due to the LPC_KBDCOOK bit getting cleared 25541480Smckusick * somewhere along the line. Hence we check and reset 25641480Smckusick * LPCTRL if necessary. 25741480Smckusick */ 25841480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READLPCTRL, NULL, 0, &lpctrl); 25941480Smckusick if ((lpctrl & LPC_KBDCOOK) == 0) { 26041480Smckusick printf("hilclose: bad LPCTRL %x, reset to %x\n", 26141480Smckusick lpctrl, lpctrl|LPC_KBDCOOK); 26241480Smckusick lpctrl |= LPC_KBDCOOK; 26341480Smckusick send_hil_cmd(hilp->hl_addr, HIL_WRITELPCTRL, 26441480Smckusick &lpctrl, 1, NULL); 26541480Smckusick } 26641480Smckusick #ifdef DEBUG 26741480Smckusick if (hildebug & HDB_KEYBOARD) 26841480Smckusick printf("hilclose: keyboard %d cooked\n", 26941480Smckusick hilp->hl_kbddev); 27041480Smckusick #endif 27153923Shibler kbdenable(HILLOOP(dev)); 27241480Smckusick } 27341480Smckusick (void) spl0(); 27441480Smckusick return (0); 27541480Smckusick } 27641480Smckusick 27741480Smckusick /* 27841480Smckusick * Read interface to HIL device. 27941480Smckusick */ 28041480Smckusick hilread(dev, uio) 28141480Smckusick dev_t dev; 28241480Smckusick register struct uio *uio; 28341480Smckusick { 28453923Shibler struct hilloop *hilp = &hilloop[HILLOOP(dev)]; 28541480Smckusick register struct hilloopdev *dptr; 28641480Smckusick register int cc; 28741480Smckusick u_char device = HILUNIT(dev); 28841480Smckusick char buf[HILBUFSIZE]; 28941480Smckusick int error; 29041480Smckusick 29141480Smckusick #if 0 29241480Smckusick /* 29341480Smckusick * XXX: Don't do this since HP-UX doesn't. 29441480Smckusick * 29541480Smckusick * Check device number. 29641480Smckusick * This check is necessary since loop can reconfigure. 29741480Smckusick */ 29841480Smckusick if (device > hilp->hl_maxdev) 29941480Smckusick return(ENODEV); 30041480Smckusick #endif 30141480Smckusick 30241480Smckusick dptr = &hilp->hl_device[device]; 30341480Smckusick if ((dptr->hd_flags & HIL_READIN) == 0) 30441480Smckusick return(ENODEV); 30541480Smckusick 30641480Smckusick (void) splhil(); 30741480Smckusick while (dptr->hd_queue.c_cc == 0) { 30841480Smckusick if (dptr->hd_flags & HIL_NOBLOCK) { 30941480Smckusick spl0(); 31041480Smckusick return(EWOULDBLOCK); 31141480Smckusick } 31241480Smckusick dptr->hd_flags |= HIL_ASLEEP; 31342360Smckusick if (error = tsleep((caddr_t)dptr, TTIPRI | PCATCH, hilin, 0)) { 31442360Smckusick (void) spl0(); 31542360Smckusick return (error); 31642360Smckusick } 31741480Smckusick } 31841480Smckusick (void) spl0(); 31941480Smckusick 32041480Smckusick error = 0; 32141480Smckusick while (uio->uio_resid > 0 && error == 0) { 32241480Smckusick cc = hilq_to_b(&dptr->hd_queue, buf, 32355070Spendry min(uio->uio_resid, HILBUFSIZE)); 32441480Smckusick if (cc <= 0) 32541480Smckusick break; 32641480Smckusick error = uiomove(buf, cc, uio); 32741480Smckusick } 32841480Smckusick return(error); 32941480Smckusick } 33041480Smckusick 33149132Skarels hilioctl(dev, cmd, data, flag, p) 33241480Smckusick dev_t dev; 333*65643Sbostic int cmd, flag; 33441480Smckusick caddr_t data; 33549132Skarels struct proc *p; 33641480Smckusick { 33753923Shibler register struct hilloop *hilp = &hilloop[HILLOOP(dev)]; 33841480Smckusick char device = HILUNIT(dev); 33941480Smckusick struct hilloopdev *dptr; 34041480Smckusick register int i; 34141480Smckusick u_char hold; 34241480Smckusick int error; 34341480Smckusick 34441480Smckusick #ifdef DEBUG 34541480Smckusick if (hildebug & HDB_FOLLOW) 34641480Smckusick printf("hilioctl(%d): dev %x cmd %x\n", 34743316Smckusick p->p_pid, device, cmd); 34841480Smckusick #endif 34941480Smckusick 35041480Smckusick dptr = &hilp->hl_device[device]; 35141480Smckusick if ((dptr->hd_flags & HIL_ALIVE) == 0) 35241480Smckusick return (ENODEV); 35341480Smckusick 35441480Smckusick /* 35541480Smckusick * Don't allow hardware ioctls on virtual devices. 35641480Smckusick * Note that though these are the BSD names, they have the same 35741480Smckusick * values as the HP-UX equivalents so we catch them as well. 35841480Smckusick */ 35941480Smckusick if (dptr->hd_flags & HIL_PSEUDO) { 36041480Smckusick switch (cmd) { 36141480Smckusick case HILIOCSC: 36241480Smckusick case HILIOCID: 36353923Shibler case OHILIOCID: 36441480Smckusick case HILIOCRN: 36541480Smckusick case HILIOCRS: 36641480Smckusick case HILIOCED: 36741480Smckusick return(ENODEV); 36841480Smckusick 36941480Smckusick /* 37041480Smckusick * XXX: should also return ENODEV but HP-UX compat 37141480Smckusick * breaks if we do. They work ok right now because 37241480Smckusick * we only recognize one keyboard on the loop. This 37341480Smckusick * will have to change if we remove that restriction. 37441480Smckusick */ 37541480Smckusick case HILIOCAROFF: 37641480Smckusick case HILIOCAR1: 37741480Smckusick case HILIOCAR2: 37841480Smckusick break; 37941480Smckusick 38041480Smckusick default: 38141480Smckusick break; 38241480Smckusick } 38341480Smckusick } 38441480Smckusick 38541480Smckusick #ifdef HPUXCOMPAT 38657309Shibler if (p->p_md.md_flags & MDP_HPUX) 38741480Smckusick return(hpuxhilioctl(dev, cmd, data, flag)); 38841480Smckusick #endif 38941480Smckusick 39041480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 39141480Smckusick bzero((caddr_t)hilp->hl_cmdbuf, HILBUFSIZE); 39241480Smckusick hilp->hl_cmddev = device; 39341480Smckusick error = 0; 39441480Smckusick switch (cmd) { 39541480Smckusick 39641480Smckusick case HILIOCSBP: 39741480Smckusick /* Send four data bytes to the tone gererator. */ 39841480Smckusick send_hil_cmd(hilp->hl_addr, HIL_STARTCMD, data, 4, NULL); 39941480Smckusick /* Send the trigger beeper command to the 8042. */ 40041480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL); 40141480Smckusick break; 40241480Smckusick 40357309Shibler case OHILIOCRRT: 40441480Smckusick case HILIOCRRT: 40541480Smckusick /* Transfer the real time to the 8042 data buffer */ 40641480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL); 40741480Smckusick /* Read each byte of the real time */ 40841480Smckusick for (i = 0; i < 5; i++) { 40941480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READTIME + i, NULL, 41041480Smckusick 0, &hold); 41141480Smckusick data[4-i] = hold; 41241480Smckusick } 41341480Smckusick break; 41441480Smckusick 41541480Smckusick case HILIOCRT: 41641480Smckusick for (i = 0; i < 4; i++) { 41741480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF) + i, 41841480Smckusick NULL, 0, &hold); 41941480Smckusick data[i] = hold; 42041480Smckusick } 42141480Smckusick break; 42241480Smckusick 42341480Smckusick case HILIOCID: 42453923Shibler case OHILIOCID: 42541480Smckusick case HILIOCSC: 42641480Smckusick case HILIOCRN: 42741480Smckusick case HILIOCRS: 42841480Smckusick case HILIOCED: 42941480Smckusick send_hildev_cmd(hilp, device, (cmd & 0xFF)); 43041480Smckusick bcopy(hilp->hl_cmdbuf, data, hilp->hl_cmdbp-hilp->hl_cmdbuf); 43141480Smckusick break; 43241480Smckusick 43341480Smckusick case HILIOCAROFF: 43441480Smckusick case HILIOCAR1: 43541480Smckusick case HILIOCAR2: 43641480Smckusick if (hilp->hl_kbddev) { 43741480Smckusick hilp->hl_cmddev = hilp->hl_kbddev; 43841480Smckusick send_hildev_cmd(hilp, hilp->hl_kbddev, (cmd & 0xFF)); 43941480Smckusick hilp->hl_kbdflags &= ~(KBD_AR1|KBD_AR2); 44041480Smckusick if (cmd == HILIOCAR1) 44141480Smckusick hilp->hl_kbdflags |= KBD_AR1; 44241480Smckusick else if (cmd == HILIOCAR2) 44341480Smckusick hilp->hl_kbdflags |= KBD_AR2; 44441480Smckusick } 44541480Smckusick break; 44641480Smckusick 44741480Smckusick case HILIOCBEEP: 44841480Smckusick hilbeep(hilp, (struct _hilbell *)data); 44941480Smckusick break; 45041480Smckusick 45141480Smckusick case FIONBIO: 45241480Smckusick dptr = &hilp->hl_device[device]; 45341480Smckusick if (*(int *)data) 45441480Smckusick dptr->hd_flags |= HIL_NOBLOCK; 45541480Smckusick else 45641480Smckusick dptr->hd_flags &= ~HIL_NOBLOCK; 45741480Smckusick break; 45841480Smckusick 45941480Smckusick /* 46041480Smckusick * FIOASYNC must be present for FIONBIO above to work! 46141480Smckusick * (See fcntl in kern_descrip.c). 46241480Smckusick */ 46341480Smckusick case FIOASYNC: 46441480Smckusick break; 46541480Smckusick 46641480Smckusick case HILIOCALLOCQ: 46753923Shibler error = hilqalloc(hilp, (struct hilqinfo *)data); 46841480Smckusick break; 46941480Smckusick 47041480Smckusick case HILIOCFREEQ: 47153923Shibler error = hilqfree(hilp, ((struct hilqinfo *)data)->qid); 47241480Smckusick break; 47341480Smckusick 47441480Smckusick case HILIOCMAPQ: 47553923Shibler error = hilqmap(hilp, *(int *)data, device); 47641480Smckusick break; 47741480Smckusick 47841480Smckusick case HILIOCUNMAPQ: 47953923Shibler error = hilqunmap(hilp, *(int *)data, device); 48041480Smckusick break; 48141480Smckusick 48241480Smckusick case HILIOCHPUX: 48341480Smckusick dptr = &hilp->hl_device[device]; 48441480Smckusick dptr->hd_flags |= HIL_READIN; 48541480Smckusick dptr->hd_flags &= ~HIL_QUEUEIN; 48641480Smckusick break; 48741480Smckusick 48841480Smckusick case HILIOCRESET: 48941480Smckusick hilreset(hilp); 49041480Smckusick break; 49141480Smckusick 49241480Smckusick #ifdef DEBUG 49341480Smckusick case HILIOCTEST: 49441480Smckusick hildebug = *(int *) data; 49541480Smckusick break; 49641480Smckusick #endif 49741480Smckusick 49841480Smckusick default: 49941480Smckusick error = EINVAL; 50041480Smckusick break; 50141480Smckusick 50241480Smckusick } 50341480Smckusick hilp->hl_cmddev = 0; 50441480Smckusick return(error); 50541480Smckusick } 50641480Smckusick 50741480Smckusick #ifdef HPUXCOMPAT 50841480Smckusick /* ARGSUSED */ 50941480Smckusick hpuxhilioctl(dev, cmd, data, flag) 51041480Smckusick dev_t dev; 511*65643Sbostic int cmd, flag; 51241480Smckusick caddr_t data; 51341480Smckusick { 51453923Shibler register struct hilloop *hilp = &hilloop[HILLOOP(dev)]; 51541480Smckusick char device = HILUNIT(dev); 51641480Smckusick struct hilloopdev *dptr; 51741480Smckusick register int i; 51841480Smckusick u_char hold; 51941480Smckusick 52041480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 52141480Smckusick bzero((caddr_t)hilp->hl_cmdbuf, HILBUFSIZE); 52241480Smckusick hilp->hl_cmddev = device; 52341480Smckusick switch (cmd) { 52441480Smckusick 52541480Smckusick case HILSC: 52641480Smckusick case HILID: 52741480Smckusick case HILRN: 52841480Smckusick case HILRS: 52941480Smckusick case HILED: 53041480Smckusick case HILP1: 53141480Smckusick case HILP2: 53241480Smckusick case HILP3: 53341480Smckusick case HILP4: 53441480Smckusick case HILP5: 53541480Smckusick case HILP6: 53641480Smckusick case HILP7: 53741480Smckusick case HILP: 53841480Smckusick case HILA1: 53941480Smckusick case HILA2: 54041480Smckusick case HILA3: 54141480Smckusick case HILA4: 54241480Smckusick case HILA5: 54341480Smckusick case HILA6: 54441480Smckusick case HILA7: 54541480Smckusick case HILA: 54641480Smckusick send_hildev_cmd(hilp, device, (cmd & 0xFF)); 54741480Smckusick bcopy(hilp->hl_cmdbuf, data, hilp->hl_cmdbp-hilp->hl_cmdbuf); 54841480Smckusick break; 54941480Smckusick 55041480Smckusick case HILDKR: 55141480Smckusick case HILER1: 55241480Smckusick case HILER2: 55341480Smckusick if (hilp->hl_kbddev) { 55441480Smckusick hilp->hl_cmddev = hilp->hl_kbddev; 55541480Smckusick send_hildev_cmd(hilp, hilp->hl_kbddev, (cmd & 0xFF)); 55641480Smckusick hilp->hl_kbdflags &= ~(KBD_AR1|KBD_AR2); 55741480Smckusick if (cmd == HILIOCAR1) 55841480Smckusick hilp->hl_kbdflags |= KBD_AR1; 55941480Smckusick else if (cmd == HILIOCAR2) 56041480Smckusick hilp->hl_kbdflags |= KBD_AR2; 56141480Smckusick } 56241480Smckusick break; 56341480Smckusick 56441480Smckusick case EFTSBP: 56541480Smckusick /* Send four data bytes to the tone gererator. */ 56641480Smckusick send_hil_cmd(hilp->hl_addr, HIL_STARTCMD, data, 4, NULL); 56741480Smckusick /* Send the trigger beeper command to the 8042. */ 56841480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL); 56941480Smckusick break; 57041480Smckusick 57141480Smckusick case EFTRRT: 57241480Smckusick /* Transfer the real time to the 8042 data buffer */ 57341480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL); 57441480Smckusick /* Read each byte of the real time */ 57541480Smckusick for (i = 0; i < 5; i++) { 57641480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READTIME + i, NULL, 57741480Smckusick 0, &hold); 57841480Smckusick data[4-i] = hold; 57941480Smckusick } 58041480Smckusick break; 58141480Smckusick 58241480Smckusick case EFTRT: 58341480Smckusick for (i = 0; i < 4; i++) { 58441480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF) + i, 58541480Smckusick NULL, 0, &hold); 58641480Smckusick data[i] = hold; 58741480Smckusick } 58841480Smckusick break; 58941480Smckusick 59041480Smckusick case EFTRLC: 59141480Smckusick case EFTRCC: 59241480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, &hold); 59341480Smckusick *data = hold; 59441480Smckusick break; 59541480Smckusick 59641480Smckusick case EFTSRPG: 59741480Smckusick case EFTSRD: 59841480Smckusick case EFTSRR: 59941480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), data, 1, NULL); 60041480Smckusick break; 60141480Smckusick 60241480Smckusick case EFTSBI: 60353923Shibler #ifdef hp800 60453923Shibler /* XXX big magic */ 60553923Shibler hold = 7 - (*(u_char *)data >> 5); 60653923Shibler *(int *)data = 0x84069008 | (hold << 8); 60753923Shibler send_hil_cmd(hilp->hl_addr, HIL_STARTCMD, data, 4, NULL); 60853923Shibler send_hil_cmd(hilp->hl_addr, 0xC4, NULL, 0, NULL); 60953923Shibler break; 61053923Shibler #else 61141480Smckusick hilbeep(hilp, (struct _hilbell *)data); 61253923Shibler #endif 61341480Smckusick break; 61441480Smckusick 61541480Smckusick case FIONBIO: 61641480Smckusick dptr = &hilp->hl_device[device]; 61741480Smckusick if (*(int *)data) 61841480Smckusick dptr->hd_flags |= HIL_NOBLOCK; 61941480Smckusick else 62041480Smckusick dptr->hd_flags &= ~HIL_NOBLOCK; 62141480Smckusick break; 62241480Smckusick 62341480Smckusick case FIOASYNC: 62441480Smckusick break; 62541480Smckusick 62641480Smckusick default: 62741480Smckusick hilp->hl_cmddev = 0; 62841480Smckusick return(EINVAL); 62941480Smckusick } 63041480Smckusick hilp->hl_cmddev = 0; 63141480Smckusick return(0); 63241480Smckusick } 63341480Smckusick #endif 63441480Smckusick 63541480Smckusick /* ARGSUSED */ 63641480Smckusick hilmap(dev, off, prot) 63741480Smckusick dev_t dev; 638*65643Sbostic int off, prot; 63941480Smckusick { 64041480Smckusick } 64141480Smckusick 64241480Smckusick /*ARGSUSED*/ 64349132Skarels hilselect(dev, rw, p) 64441480Smckusick dev_t dev; 645*65643Sbostic int rw; 64649132Skarels struct proc *p; 64741480Smckusick { 64853923Shibler register struct hilloop *hilp = &hilloop[HILLOOP(dev)]; 64941480Smckusick register struct hilloopdev *dptr; 65041480Smckusick register struct hiliqueue *qp; 65141480Smckusick register int mask; 65241480Smckusick int s, device; 65341480Smckusick 65441480Smckusick if (rw == FWRITE) 65541480Smckusick return (1); 65641480Smckusick device = HILUNIT(dev); 65741480Smckusick 65841480Smckusick /* 65941480Smckusick * Read interface. 66041480Smckusick * Return 1 if there is something in the queue, 0 ow. 66141480Smckusick */ 66241480Smckusick dptr = &hilp->hl_device[device]; 66341480Smckusick if (dptr->hd_flags & HIL_READIN) { 66441480Smckusick s = splhil(); 66541480Smckusick if (dptr->hd_queue.c_cc) { 66641480Smckusick splx(s); 66741480Smckusick return (1); 66841480Smckusick } 66952533Smckusick selrecord(p, &dptr->hd_selr); 67041480Smckusick splx(s); 67141480Smckusick return (0); 67241480Smckusick } 67341480Smckusick 67441480Smckusick /* 67541480Smckusick * Make sure device is alive and real (or the loop device). 67641480Smckusick * Note that we do not do this for the read interface. 67741480Smckusick * This is primarily to be consistant with HP-UX. 67841480Smckusick */ 67941480Smckusick if (device && (dptr->hd_flags & (HIL_ALIVE|HIL_PSEUDO)) != HIL_ALIVE) 68041480Smckusick return (1); 68141480Smckusick 68241480Smckusick /* 68341480Smckusick * Select on loop device is special. 68441480Smckusick * Check to see if there are any data for any loop device 68541480Smckusick * provided it is associated with a queue belonging to this user. 68641480Smckusick */ 68741480Smckusick if (device == 0) 68841480Smckusick mask = -1; 68941480Smckusick else 69041480Smckusick mask = hildevmask(device); 69141480Smckusick /* 69241480Smckusick * Must check everybody with interrupts blocked to prevent races. 69341480Smckusick */ 69441480Smckusick s = splhil(); 69541480Smckusick for (qp = hilp->hl_queue; qp < &hilp->hl_queue[NHILQ]; qp++) 69643316Smckusick if (qp->hq_procp == p && (mask & qp->hq_devmask) && 69741480Smckusick qp->hq_eventqueue->hil_evqueue.head != 69841480Smckusick qp->hq_eventqueue->hil_evqueue.tail) { 69941480Smckusick splx(s); 70041480Smckusick return (1); 70141480Smckusick } 70241480Smckusick 70352533Smckusick selrecord(p, &dptr->hd_selr); 70441480Smckusick splx(s); 70541480Smckusick return (0); 70641480Smckusick } 70741480Smckusick 70853923Shibler /*ARGSUSED*/ 70953923Shibler hilint(unit) 710*65643Sbostic int unit; 71141480Smckusick { 71253923Shibler #ifdef hp300 71353923Shibler struct hilloop *hilp = &hilloop[0]; /* XXX how do we know on 300? */ 71453923Shibler #else 71553923Shibler struct hilloop *hilp = &hilloop[unit]; 71653923Shibler #endif 71741480Smckusick register struct hil_dev *hildevice = hilp->hl_addr; 71841480Smckusick u_char c, stat; 71941480Smckusick 72053923Shibler stat = READHILSTAT(hildevice); 72153923Shibler c = READHILDATA(hildevice); /* clears interrupt */ 72253923Shibler hil_process_int(hilp, stat, c); 72341480Smckusick } 72441480Smckusick 72541480Smckusick #include "ite.h" 72641480Smckusick 72753923Shibler hil_process_int(hilp, stat, c) 72853923Shibler register struct hilloop *hilp; 72941480Smckusick register u_char stat, c; 73041480Smckusick { 73141480Smckusick #ifdef DEBUG 73241480Smckusick if (hildebug & HDB_EVENTS) 73341480Smckusick printf("hilint: %x %x\n", stat, c); 73441480Smckusick #endif 73541480Smckusick 73641480Smckusick /* the shift enables the compiler to generate a jump table */ 73741480Smckusick switch ((stat>>HIL_SSHIFT) & HIL_SMASK) { 73841480Smckusick 73941480Smckusick #if NITE > 0 74041480Smckusick case HIL_KEY: 74141480Smckusick case HIL_SHIFT: 74241480Smckusick case HIL_CTRL: 74341480Smckusick case HIL_CTRLSHIFT: 74441480Smckusick itefilter(stat, c); 74541480Smckusick return; 74641480Smckusick #endif 74741480Smckusick 74841480Smckusick case HIL_STATUS: /* The status info. */ 74941480Smckusick if (c & HIL_ERROR) { 75041480Smckusick hilp->hl_cmddone = TRUE; 75141480Smckusick if (c == HIL_RECONFIG) 75241480Smckusick hilconfig(hilp); 75341480Smckusick break; 75441480Smckusick } 75541480Smckusick if (c & HIL_COMMAND) { 75641480Smckusick if (c & HIL_POLLDATA) /* End of data */ 75741480Smckusick hilevent(hilp); 75841480Smckusick else /* End of command */ 75941480Smckusick hilp->hl_cmdending = TRUE; 76041480Smckusick hilp->hl_actdev = 0; 76141480Smckusick } else { 76241480Smckusick if (c & HIL_POLLDATA) { /* Start of polled data */ 76341480Smckusick if (hilp->hl_actdev != 0) 76441480Smckusick hilevent(hilp); 76541480Smckusick hilp->hl_actdev = (c & HIL_DEVMASK); 76641480Smckusick hilp->hl_pollbp = hilp->hl_pollbuf; 76741480Smckusick } else { /* Start of command */ 76841480Smckusick if (hilp->hl_cmddev == (c & HIL_DEVMASK)) { 76941480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 77041480Smckusick hilp->hl_actdev = 0; 77141480Smckusick } 77241480Smckusick } 77341480Smckusick } 77441480Smckusick return; 77541480Smckusick 77641480Smckusick case HIL_DATA: 77741480Smckusick if (hilp->hl_actdev != 0) /* Collecting poll data */ 77841480Smckusick *hilp->hl_pollbp++ = c; 77941480Smckusick else if (hilp->hl_cmddev != 0) /* Collecting cmd data */ 78041480Smckusick if (hilp->hl_cmdending) { 78141480Smckusick hilp->hl_cmddone = TRUE; 78241480Smckusick hilp->hl_cmdending = FALSE; 78341480Smckusick } else 78441480Smckusick *hilp->hl_cmdbp++ = c; 78541480Smckusick return; 78641480Smckusick 78741480Smckusick case 0: /* force full jump table */ 78841480Smckusick default: 78941480Smckusick return; 79041480Smckusick } 79141480Smckusick } 79241480Smckusick 79341480Smckusick #if defined(DEBUG) && !defined(PANICBUTTON) 79441480Smckusick #define PANICBUTTON 79541480Smckusick #endif 79641480Smckusick 79741480Smckusick /* 79841480Smckusick * Optimized macro to compute: 79941480Smckusick * eq->head == (eq->tail + 1) % eq->size 80041480Smckusick * i.e. has tail caught up with head. We do this because 32 bit long 80141480Smckusick * remaidering is expensive (a function call with our compiler). 80241480Smckusick */ 80341480Smckusick #define HQFULL(eq) (((eq)->head?(eq)->head:(eq)->size) == (eq)->tail+1) 80441480Smckusick #define HQVALID(eq) \ 80541480Smckusick ((eq)->size == HEVQSIZE && (eq)->tail >= 0 && (eq)->tail < HEVQSIZE) 80641480Smckusick 80741480Smckusick hilevent(hilp) 80841480Smckusick struct hilloop *hilp; 80941480Smckusick { 81041480Smckusick register struct hilloopdev *dptr = &hilp->hl_device[hilp->hl_actdev]; 81141480Smckusick register int len, mask, qnum; 81241480Smckusick register u_char *cp, *pp; 81341480Smckusick register HILQ *hq; 81441480Smckusick struct timeval ourtime; 81541480Smckusick hil_packet *proto; 81641480Smckusick int s, len0; 81741480Smckusick long tenths; 81841480Smckusick 81941480Smckusick #ifdef PANICBUTTON 82041480Smckusick static int first; 82141480Smckusick extern int panicbutton; 82241480Smckusick 82341480Smckusick cp = hilp->hl_pollbuf; 82441480Smckusick if (panicbutton && (*cp & HIL_KBDDATA)) { 82541480Smckusick if (*++cp == 0x4E) 82641480Smckusick first = 1; 82741480Smckusick else if (first && *cp == 0x46 && !panicstr) 82841480Smckusick panic("are we having fun yet?"); 82941480Smckusick else 83041480Smckusick first = 0; 83141480Smckusick } 83241480Smckusick #endif 83341480Smckusick #ifdef DEBUG 83441480Smckusick if (hildebug & HDB_EVENTS) { 83541480Smckusick printf("hilevent: dev %d pollbuf: ", hilp->hl_actdev); 83641480Smckusick printhilpollbuf(hilp); 83741480Smckusick printf("\n"); 83841480Smckusick } 83941480Smckusick #endif 84041480Smckusick 84141480Smckusick /* 84241480Smckusick * Note that HIL_READIN effectively "shuts off" any queues 84341480Smckusick * that may have been in use at the time of an HILIOCHPUX call. 84441480Smckusick */ 84541480Smckusick if (dptr->hd_flags & HIL_READIN) { 84641480Smckusick hpuxhilevent(hilp, dptr); 84741480Smckusick return; 84841480Smckusick } 84941480Smckusick 85041480Smckusick /* 85141480Smckusick * If this device isn't on any queue or there are no data 85241480Smckusick * in the packet (can this happen?) do nothing. 85341480Smckusick */ 85441480Smckusick if (dptr->hd_qmask == 0 || 85541480Smckusick (len0 = hilp->hl_pollbp - hilp->hl_pollbuf) <= 0) 85641480Smckusick return; 85741480Smckusick 85841480Smckusick /* 85941480Smckusick * Everybody gets the same time stamp 86041480Smckusick */ 86141480Smckusick s = splclock(); 86241480Smckusick ourtime = time; 86341480Smckusick splx(s); 86441480Smckusick tenths = (ourtime.tv_sec * 100) + (ourtime.tv_usec / 10000); 86541480Smckusick 86641480Smckusick proto = NULL; 86741480Smckusick mask = dptr->hd_qmask; 86841480Smckusick for (qnum = 0; mask; qnum++) { 86941480Smckusick if ((mask & hilqmask(qnum)) == 0) 87041480Smckusick continue; 87141480Smckusick mask &= ~hilqmask(qnum); 87241480Smckusick hq = hilp->hl_queue[qnum].hq_eventqueue; 87341480Smckusick 87441480Smckusick /* 87541480Smckusick * Ensure that queue fields that we rely on are valid 87641480Smckusick * and that there is space in the queue. If either 87741480Smckusick * test fails, we just skip this queue. 87841480Smckusick */ 87941480Smckusick if (!HQVALID(&hq->hil_evqueue) || HQFULL(&hq->hil_evqueue)) 88041480Smckusick continue; 88141480Smckusick 88241480Smckusick /* 88341480Smckusick * Copy data to queue. 88441480Smckusick * If this is the first queue we construct the packet 88541480Smckusick * with length, timestamp and poll buffer data. 88641480Smckusick * For second and sucessive packets we just duplicate 88741480Smckusick * the first packet. 88841480Smckusick */ 88941480Smckusick pp = (u_char *) &hq->hil_event[hq->hil_evqueue.tail]; 89041480Smckusick if (proto == NULL) { 89141480Smckusick proto = (hil_packet *)pp; 89241480Smckusick cp = hilp->hl_pollbuf; 89341480Smckusick len = len0; 89441480Smckusick *pp++ = len + 6; 89541480Smckusick *pp++ = hilp->hl_actdev; 89641480Smckusick *(long *)pp = tenths; 89741480Smckusick pp += sizeof(long); 89841480Smckusick do *pp++ = *cp++; while (--len); 89941480Smckusick } else 90041480Smckusick *(hil_packet *)pp = *proto; 90141480Smckusick 90241480Smckusick if (++hq->hil_evqueue.tail == hq->hil_evqueue.size) 90341480Smckusick hq->hil_evqueue.tail = 0; 90441480Smckusick } 90541480Smckusick 90641480Smckusick /* 90741480Smckusick * Wake up anyone selecting on this device or the loop itself 90841480Smckusick */ 90952533Smckusick selwakeup(&dptr->hd_selr); 91041480Smckusick dptr = &hilp->hl_device[HILLOOPDEV]; 91152533Smckusick selwakeup(&dptr->hd_selr); 91241480Smckusick } 91341480Smckusick 91441480Smckusick #undef HQFULL 91541480Smckusick 91641480Smckusick hpuxhilevent(hilp, dptr) 91741480Smckusick register struct hilloop *hilp; 91841480Smckusick register struct hilloopdev *dptr; 91941480Smckusick { 92041480Smckusick register int len; 92141480Smckusick struct timeval ourtime; 92241480Smckusick long tstamp; 92341480Smckusick int s; 92441480Smckusick 92541480Smckusick /* 92641480Smckusick * Everybody gets the same time stamp 92741480Smckusick */ 92841480Smckusick s = splclock(); 92941480Smckusick ourtime = time; 93041480Smckusick splx(s); 93141480Smckusick tstamp = (ourtime.tv_sec * 100) + (ourtime.tv_usec / 10000); 93241480Smckusick 93341480Smckusick /* 93441480Smckusick * Each packet that goes into the buffer must be preceded by the 93541480Smckusick * number of bytes in the packet, and the timestamp of the packet. 93641480Smckusick * This adds 5 bytes to the packet size. Make sure there is enough 93741480Smckusick * room in the buffer for it, and if not, toss the packet. 93841480Smckusick */ 93941480Smckusick len = hilp->hl_pollbp - hilp->hl_pollbuf; 94041480Smckusick if (dptr->hd_queue.c_cc <= (HILMAXCLIST - (len+5))) { 94141480Smckusick putc(len+5, &dptr->hd_queue); 94241480Smckusick (void) b_to_q((char *)&tstamp, sizeof tstamp, &dptr->hd_queue); 94341480Smckusick (void) b_to_q((char *)hilp->hl_pollbuf, len, &dptr->hd_queue); 94441480Smckusick } 94541480Smckusick 94641480Smckusick /* 94741480Smckusick * Wake up any one blocked on a read or select 94841480Smckusick */ 94941480Smckusick if (dptr->hd_flags & HIL_ASLEEP) { 95041480Smckusick dptr->hd_flags &= ~HIL_ASLEEP; 95141480Smckusick wakeup((caddr_t)dptr); 95241480Smckusick } 95352533Smckusick selwakeup(&dptr->hd_selr); 95441480Smckusick } 95541480Smckusick 95641480Smckusick /* 95741480Smckusick * Shared queue manipulation routines 95841480Smckusick */ 95941480Smckusick 96053923Shibler hilqalloc(hilp, qip) 96153923Shibler register struct hilloop *hilp; 96241480Smckusick struct hilqinfo *qip; 96341480Smckusick { 96449132Skarels struct proc *p = curproc; /* XXX */ 96541480Smckusick 96641480Smckusick #ifdef DEBUG 96741480Smckusick if (hildebug & HDB_FOLLOW) 96845750Smckusick printf("hilqalloc(%d): addr %x\n", p->p_pid, qip->addr); 96941480Smckusick #endif 97041480Smckusick return(EINVAL); 97141480Smckusick } 97241480Smckusick 97353923Shibler hilqfree(hilp, qnum) 974*65643Sbostic register struct hilloop *hilp; 97541480Smckusick register int qnum; 97641480Smckusick { 97749132Skarels struct proc *p = curproc; /* XXX */ 97841480Smckusick 97941480Smckusick #ifdef DEBUG 98041480Smckusick if (hildebug & HDB_FOLLOW) 98145750Smckusick printf("hilqfree(%d): qnum %d\n", p->p_pid, qnum); 98241480Smckusick #endif 98341480Smckusick return(EINVAL); 98441480Smckusick } 98541480Smckusick 98653923Shibler hilqmap(hilp, qnum, device) 98753923Shibler register struct hilloop *hilp; 98841480Smckusick register int qnum, device; 98941480Smckusick { 99049132Skarels struct proc *p = curproc; /* XXX */ 99141480Smckusick register struct hilloopdev *dptr = &hilp->hl_device[device]; 99241480Smckusick int s; 99341480Smckusick 99441480Smckusick #ifdef DEBUG 99541480Smckusick if (hildebug & HDB_FOLLOW) 99641480Smckusick printf("hilqmap(%d): qnum %d device %x\n", 99743316Smckusick p->p_pid, qnum, device); 99841480Smckusick #endif 99943316Smckusick if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p) 100041480Smckusick return(EINVAL); 100141480Smckusick if ((dptr->hd_flags & HIL_QUEUEIN) == 0) 100241480Smckusick return(EINVAL); 100349132Skarels if (dptr->hd_qmask && p->p_ucred->cr_uid && 100449132Skarels p->p_ucred->cr_uid != dptr->hd_uid) 100541480Smckusick return(EPERM); 100641480Smckusick 100741480Smckusick hilp->hl_queue[qnum].hq_devmask |= hildevmask(device); 100841480Smckusick if (dptr->hd_qmask == 0) 100949132Skarels dptr->hd_uid = p->p_ucred->cr_uid; 101041480Smckusick s = splhil(); 101141480Smckusick dptr->hd_qmask |= hilqmask(qnum); 101241480Smckusick splx(s); 101341480Smckusick #ifdef DEBUG 101441480Smckusick if (hildebug & HDB_MASK) 101541480Smckusick printf("hilqmap(%d): devmask %x qmask %x\n", 101643316Smckusick p->p_pid, hilp->hl_queue[qnum].hq_devmask, 101741480Smckusick dptr->hd_qmask); 101841480Smckusick #endif 101941480Smckusick return(0); 102041480Smckusick } 102141480Smckusick 102253923Shibler hilqunmap(hilp, qnum, device) 102353923Shibler register struct hilloop *hilp; 102441480Smckusick register int qnum, device; 102541480Smckusick { 102649132Skarels struct proc *p = curproc; /* XXX */ 102741480Smckusick int s; 102841480Smckusick 102941480Smckusick #ifdef DEBUG 103041480Smckusick if (hildebug & HDB_FOLLOW) 103141480Smckusick printf("hilqunmap(%d): qnum %d device %x\n", 103243316Smckusick p->p_pid, qnum, device); 103341480Smckusick #endif 103441480Smckusick 103543316Smckusick if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p) 103641480Smckusick return(EINVAL); 103741480Smckusick 103841480Smckusick hilp->hl_queue[qnum].hq_devmask &= ~hildevmask(device); 103941480Smckusick s = splhil(); 104041480Smckusick hilp->hl_device[device].hd_qmask &= ~hilqmask(qnum); 104141480Smckusick splx(s); 104241480Smckusick #ifdef DEBUG 104341480Smckusick if (hildebug & HDB_MASK) 104441480Smckusick printf("hilqunmap(%d): devmask %x qmask %x\n", 104543316Smckusick p->p_pid, hilp->hl_queue[qnum].hq_devmask, 104641480Smckusick hilp->hl_device[device].hd_qmask); 104741480Smckusick #endif 104841480Smckusick return(0); 104941480Smckusick } 105041480Smckusick 105141480Smckusick /* 105241480Smckusick * Cooked keyboard functions for ite driver. 105341480Smckusick * There is only one "cooked" ITE keyboard (the first keyboard found) 105441480Smckusick * per loop. There may be other keyboards, but they will always be "raw". 105541480Smckusick */ 105641480Smckusick 105753923Shibler kbdbell(unit) 105853923Shibler int unit; 105941480Smckusick { 106053923Shibler struct hilloop *hilp = &hilloop[unit]; 106141480Smckusick 106241480Smckusick hilbeep(hilp, &default_bell); 106341480Smckusick } 106441480Smckusick 106553923Shibler kbdenable(unit) 106653923Shibler int unit; 106741480Smckusick { 106853923Shibler struct hilloop *hilp = &hilloop[unit]; 106941480Smckusick register struct hil_dev *hildevice = hilp->hl_addr; 107041480Smckusick char db; 107141480Smckusick 107241480Smckusick /* Set the autorepeat rate register */ 107341480Smckusick db = ar_format(KBD_ARR); 107441480Smckusick send_hil_cmd(hildevice, HIL_SETARR, &db, 1, NULL); 107541480Smckusick 107641480Smckusick /* Set the autorepeat delay register */ 107741480Smckusick db = ar_format(KBD_ARD); 107841480Smckusick send_hil_cmd(hildevice, HIL_SETARD, &db, 1, NULL); 107941480Smckusick 108041480Smckusick /* Enable interrupts */ 108141480Smckusick send_hil_cmd(hildevice, HIL_INTON, NULL, 0, NULL); 108241480Smckusick } 108341480Smckusick 108453923Shibler kbddisable(unit) 108553923Shibler int unit; 108641480Smckusick { 108741480Smckusick } 108841480Smckusick 108941480Smckusick /* 109041480Smckusick * XXX: read keyboard directly and return code. 109141480Smckusick * Used by console getchar routine. Could really screw up anybody 109241480Smckusick * reading from the keyboard in the normal, interrupt driven fashion. 109341480Smckusick */ 109453923Shibler kbdgetc(unit, statp) 109553923Shibler int unit, *statp; 109641480Smckusick { 109753923Shibler struct hilloop *hilp = &hilloop[unit]; 109841480Smckusick register struct hil_dev *hildevice = hilp->hl_addr; 109941480Smckusick register int c, stat; 110041480Smckusick int s; 110141480Smckusick 110241480Smckusick s = splhil(); 110353923Shibler while (((stat = READHILSTAT(hildevice)) & HIL_DATA_RDY) == 0) 110441480Smckusick ; 110553923Shibler c = READHILDATA(hildevice); 110641480Smckusick splx(s); 110741480Smckusick *statp = stat; 110841480Smckusick return(c); 110941480Smckusick } 111041480Smckusick 111141480Smckusick /* 111241480Smckusick * Recoginize and clear keyboard generated NMIs. 111341480Smckusick * Returns 1 if it was ours, 0 otherwise. Note that we cannot use 111441480Smckusick * send_hil_cmd() to issue the clear NMI command as that would actually 111541480Smckusick * lower the priority to splimp() and it doesn't wait for the completion 111641480Smckusick * of the command. Either of these conditions could result in the 111741480Smckusick * interrupt reoccuring. Note that we issue the CNMT command twice. 111841480Smckusick * This seems to be needed, once is not always enough!?! 111941480Smckusick */ 112053923Shibler kbdnmi(unit) 112153923Shibler int unit; 112241480Smckusick { 112353923Shibler #ifdef hp300 112453923Shibler struct hilloop *hilp = &hilloop[0]; /* XXX how do we know on 300? */ 112553923Shibler #else 112653923Shibler struct hilloop *hilp = &hilloop[unit]; 112753923Shibler #endif 112853923Shibler #ifdef hp300 112941480Smckusick if ((*KBDNMISTAT & KBDNMI) == 0) 113041480Smckusick return(0); 113153923Shibler #endif 113241480Smckusick HILWAIT(hilp->hl_addr); 113353923Shibler WRITEHILCMD(hilp->hl_addr, HIL_CNMT); 113441480Smckusick HILWAIT(hilp->hl_addr); 113553923Shibler WRITEHILCMD(hilp->hl_addr, HIL_CNMT); 113641480Smckusick HILWAIT(hilp->hl_addr); 113741480Smckusick return(1); 113841480Smckusick } 113941480Smckusick 114041480Smckusick #define HILSECURITY 0x33 114141480Smckusick #define HILIDENTIFY 0x03 114241480Smckusick #define HILSCBIT 0x04 114341480Smckusick 114441480Smckusick /* 114541480Smckusick * Called at boot time to print out info about interesting devices 114641480Smckusick */ 114753923Shibler hilinfo(unit) 114853923Shibler int unit; 114941480Smckusick { 115053923Shibler register struct hilloop *hilp = &hilloop[unit]; 115141480Smckusick register int id, len; 115241480Smckusick register struct kbdmap *km; 115341480Smckusick 115441480Smckusick /* 115541480Smckusick * Keyboard info. 115641480Smckusick */ 115741480Smckusick if (hilp->hl_kbddev) { 115841480Smckusick printf("hil%d: ", hilp->hl_kbddev); 115941480Smckusick for (km = kbd_map; km->kbd_code; km++) 116041480Smckusick if (km->kbd_code == hilp->hl_kbdlang) { 116141480Smckusick printf("%s ", km->kbd_desc); 116241480Smckusick break; 116341480Smckusick } 116441480Smckusick printf("keyboard\n"); 116541480Smckusick } 116641480Smckusick /* 116741480Smckusick * ID module. 116841480Smckusick * Attempt to locate the first ID module and print out its 116941480Smckusick * security code. Is this a good idea?? 117041480Smckusick */ 117141480Smckusick id = hiliddev(hilp); 117241480Smckusick if (id) { 117341480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 117441480Smckusick hilp->hl_cmddev = id; 117541480Smckusick send_hildev_cmd(hilp, id, HILSECURITY); 117641480Smckusick len = hilp->hl_cmdbp - hilp->hl_cmdbuf; 117741480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 117841480Smckusick hilp->hl_cmddev = 0; 117941480Smckusick printf("hil%d: security code", id); 118041480Smckusick for (id = 0; id < len; id++) 118141480Smckusick printf(" %x", hilp->hl_cmdbuf[id]); 118241480Smckusick while (id++ < 16) 118341480Smckusick printf(" 0"); 118441480Smckusick printf("\n"); 118541480Smckusick } 118641480Smckusick } 118741480Smckusick 118841480Smckusick #define HILAR1 0x3E 118941480Smckusick #define HILAR2 0x3F 119041480Smckusick 119141480Smckusick /* 119241480Smckusick * Called after the loop has reconfigured. Here we need to: 119341480Smckusick * - determine how many devices are on the loop 119441480Smckusick * (some may have been added or removed) 119541480Smckusick * - locate the ITE keyboard (if any) and ensure 119641480Smckusick * that it is in the proper state (raw or cooked) 119741480Smckusick * and is set to use the proper language mapping table 119841480Smckusick * - ensure all other keyboards are raw 119941480Smckusick * Note that our device state is now potentially invalid as 120041480Smckusick * devices may no longer be where they were. What we should 120141480Smckusick * do here is either track where the devices went and move 120241480Smckusick * state around accordingly or, more simply, just mark all 120341480Smckusick * devices as HIL_DERROR and don't allow any further use until 120441480Smckusick * they are closed. This is a little too brutal for my tastes, 120541480Smckusick * we prefer to just assume people won't move things around. 120641480Smckusick */ 120741480Smckusick hilconfig(hilp) 120841480Smckusick register struct hilloop *hilp; 120941480Smckusick { 121041480Smckusick u_char db; 121141480Smckusick int s; 121241480Smckusick 121341480Smckusick s = splhil(); 121441480Smckusick #ifdef DEBUG 121541480Smckusick if (hildebug & HDB_CONFIG) { 121641480Smckusick printf("hilconfig: reconfigured: "); 121741480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READLPSTAT, NULL, 0, &db); 121841480Smckusick printf("LPSTAT %x, ", db); 121941480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READLPCTRL, NULL, 0, &db); 122041480Smckusick printf("LPCTRL %x, ", db); 122141480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READKBDSADR, NULL, 0, &db); 122241480Smckusick printf("KBDSADR %x\n", db); 122341480Smckusick hilreport(hilp); 122441480Smckusick } 122541480Smckusick #endif 122641480Smckusick /* 122741480Smckusick * Determine how many devices are on the loop. 122841480Smckusick * Mark those as alive and real, all others as dead. 122941480Smckusick */ 123041480Smckusick db = 0; 123141480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READLPSTAT, NULL, 0, &db); 123241480Smckusick hilp->hl_maxdev = db & LPS_DEVMASK; 123353923Shibler #ifdef DEBUG 123453923Shibler if (hildebug & HDB_CONFIG) 123553923Shibler printf("hilconfig: %d devices found\n", hilp->hl_maxdev); 123653923Shibler #endif 123741480Smckusick for (db = 1; db < NHILD; db++) { 123841480Smckusick if (db <= hilp->hl_maxdev) 123941480Smckusick hilp->hl_device[db].hd_flags |= HIL_ALIVE; 124041480Smckusick else 124141480Smckusick hilp->hl_device[db].hd_flags &= ~HIL_ALIVE; 124241480Smckusick hilp->hl_device[db].hd_flags &= ~HIL_PSEUDO; 124341480Smckusick } 124441480Smckusick #ifdef DEBUG 124541480Smckusick if (hildebug & (HDB_CONFIG|HDB_KEYBOARD)) 124641480Smckusick printf("hilconfig: max device %d\n", hilp->hl_maxdev); 124741480Smckusick #endif 124841480Smckusick if (hilp->hl_maxdev == 0) { 124941480Smckusick hilp->hl_kbddev = 0; 125041480Smckusick splx(s); 125141480Smckusick return; 125241480Smckusick } 125341480Smckusick /* 125441480Smckusick * Find out where the keyboards are and record the ITE keyboard 125541480Smckusick * (first one found). If no keyboards found, we are all done. 125641480Smckusick */ 125741480Smckusick db = 0; 125841480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READKBDSADR, NULL, 0, &db); 125941480Smckusick #ifdef DEBUG 126041480Smckusick if (hildebug & HDB_KEYBOARD) 126141480Smckusick printf("hilconfig: keyboard: KBDSADR %x, old %d, new %d\n", 126241480Smckusick db, hilp->hl_kbddev, ffs((int)db)); 126341480Smckusick #endif 126441480Smckusick hilp->hl_kbddev = ffs((int)db); 126541480Smckusick if (hilp->hl_kbddev == 0) { 126641480Smckusick splx(s); 126741480Smckusick return; 126841480Smckusick } 126941480Smckusick /* 127041480Smckusick * Determine if the keyboard should be cooked or raw and configure it. 127141480Smckusick */ 127241480Smckusick db = (hilp->hl_kbdflags & KBD_RAW) ? 0 : 1 << (hilp->hl_kbddev - 1); 127341480Smckusick send_hil_cmd(hilp->hl_addr, HIL_WRITEKBDSADR, &db, 1, NULL); 127441480Smckusick /* 127541480Smckusick * Re-enable autorepeat in raw mode, cooked mode AR is not affected. 127641480Smckusick */ 127741480Smckusick if (hilp->hl_kbdflags & (KBD_AR1|KBD_AR2)) { 127841480Smckusick db = (hilp->hl_kbdflags & KBD_AR1) ? HILAR1 : HILAR2; 127941480Smckusick hilp->hl_cmddev = hilp->hl_kbddev; 128041480Smckusick send_hildev_cmd(hilp, hilp->hl_kbddev, db); 128141480Smckusick hilp->hl_cmddev = 0; 128241480Smckusick } 128341480Smckusick /* 128441480Smckusick * Determine the keyboard language configuration, but don't 128541480Smckusick * override a user-specified setting. 128641480Smckusick */ 128741480Smckusick db = 0; 128841480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READKBDLANG, NULL, 0, &db); 128941480Smckusick #ifdef DEBUG 129041480Smckusick if (hildebug & HDB_KEYBOARD) 129141480Smckusick printf("hilconfig: language: old %x new %x\n", 129241480Smckusick hilp->hl_kbdlang, db); 129341480Smckusick #endif 129441480Smckusick if (hilp->hl_kbdlang != KBD_SPECIAL) { 129541480Smckusick struct kbdmap *km; 129641480Smckusick 129741480Smckusick for (km = kbd_map; km->kbd_code; km++) 129841480Smckusick if (km->kbd_code == db) { 129941480Smckusick hilp->hl_kbdlang = db; 130041480Smckusick /* XXX */ 130141480Smckusick kbd_keymap = km->kbd_keymap; 130241480Smckusick kbd_shiftmap = km->kbd_shiftmap; 130341480Smckusick kbd_ctrlmap = km->kbd_ctrlmap; 130441480Smckusick kbd_ctrlshiftmap = km->kbd_ctrlshiftmap; 130541480Smckusick kbd_stringmap = km->kbd_stringmap; 130641480Smckusick } 130741480Smckusick } 130841480Smckusick splx(s); 130941480Smckusick } 131041480Smckusick 131141480Smckusick hilreset(hilp) 131241480Smckusick struct hilloop *hilp; 131341480Smckusick { 131441480Smckusick register struct hil_dev *hildevice = hilp->hl_addr; 131541480Smckusick u_char db; 131641480Smckusick 131753923Shibler #ifdef DEBUG 131853923Shibler if (hildebug & HDB_FOLLOW) 131953923Shibler printf("hilreset(%x)\n", hilp); 132053923Shibler #endif 132141480Smckusick /* 132241480Smckusick * Initialize the loop: reconfigure, don't report errors, 132341480Smckusick * cook keyboards, and enable autopolling. 132441480Smckusick */ 132541480Smckusick db = LPC_RECONF | LPC_KBDCOOK | LPC_NOERROR | LPC_AUTOPOLL; 132641480Smckusick send_hil_cmd(hildevice, HIL_WRITELPCTRL, &db, 1, NULL); 132741480Smckusick /* 132841480Smckusick * Delay one second for reconfiguration and then read the the 132941480Smckusick * data register to clear the interrupt (if the loop reconfigured). 133041480Smckusick */ 133141480Smckusick DELAY(1000000); 133253923Shibler if (READHILSTAT(hildevice) & HIL_DATA_RDY) 133353923Shibler db = READHILDATA(hildevice); 133441480Smckusick /* 133541480Smckusick * The HIL loop may have reconfigured. If so we proceed on, 133641480Smckusick * if not we loop until a successful reconfiguration is reported 133741480Smckusick * back to us. The HIL loop will continue to attempt forever. 133841480Smckusick * Probably not very smart. 133941480Smckusick */ 134041480Smckusick do { 134141480Smckusick send_hil_cmd(hildevice, HIL_READLPSTAT, NULL, 0, &db); 134241480Smckusick } while ((db & (LPS_CONFFAIL|LPS_CONFGOOD)) == 0); 134341480Smckusick /* 134441480Smckusick * At this point, the loop should have reconfigured. 134541480Smckusick * The reconfiguration interrupt has already called hilconfig() 134643411Shibler * so the keyboard has been determined. 134741480Smckusick */ 134841480Smckusick send_hil_cmd(hildevice, HIL_INTON, NULL, 0, NULL); 134941480Smckusick } 135041480Smckusick 135141480Smckusick hilbeep(hilp, bp) 135241480Smckusick struct hilloop *hilp; 135341480Smckusick register struct _hilbell *bp; 135441480Smckusick { 135541480Smckusick u_char buf[2]; 135641480Smckusick 135741480Smckusick buf[0] = ~((bp->duration - 10) / 10); 135841480Smckusick buf[1] = bp->frequency; 135941480Smckusick send_hil_cmd(hilp->hl_addr, HIL_SETTONE, buf, 2, NULL); 136041480Smckusick } 136141480Smckusick 136241480Smckusick /* 136341480Smckusick * Locate and return the address of the first ID module, 0 if none present. 136441480Smckusick */ 136541480Smckusick hiliddev(hilp) 136641480Smckusick register struct hilloop *hilp; 136741480Smckusick { 136841480Smckusick register int i, len; 136941480Smckusick 137041480Smckusick #ifdef DEBUG 137141480Smckusick if (hildebug & HDB_IDMODULE) 137253923Shibler printf("hiliddev(%x): max %d, looking for idmodule...", 137353923Shibler hilp, hilp->hl_maxdev); 137441480Smckusick #endif 137541480Smckusick for (i = 1; i <= hilp->hl_maxdev; i++) { 137641480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 137741480Smckusick hilp->hl_cmddev = i; 137841480Smckusick send_hildev_cmd(hilp, i, HILIDENTIFY); 137941480Smckusick /* 138041480Smckusick * XXX: the final condition checks to ensure that the 138141480Smckusick * device ID byte is in the range of the ID module (0x30-0x3F) 138241480Smckusick */ 138341480Smckusick len = hilp->hl_cmdbp - hilp->hl_cmdbuf; 138441480Smckusick if (len > 1 && (hilp->hl_cmdbuf[1] & HILSCBIT) && 138541480Smckusick (hilp->hl_cmdbuf[0] & 0xF0) == 0x30) { 138641480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 138741480Smckusick hilp->hl_cmddev = i; 138841480Smckusick send_hildev_cmd(hilp, i, HILSECURITY); 138941480Smckusick break; 139041480Smckusick } 139141480Smckusick } 139241480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 139341480Smckusick hilp->hl_cmddev = 0; 139441480Smckusick #ifdef DEBUG 139541480Smckusick if (hildebug & HDB_IDMODULE) 139641480Smckusick if (i <= hilp->hl_maxdev) 139741480Smckusick printf("found at %d\n", i); 139841480Smckusick else 139941480Smckusick printf("not found\n"); 140041480Smckusick #endif 140141480Smckusick return(i <= hilp->hl_maxdev ? i : 0); 140241480Smckusick } 140341480Smckusick 140453923Shibler #ifdef HPUXCOMPAT 140541480Smckusick /* 140653923Shibler * XXX map devno as expected by HP-UX 140753923Shibler */ 140853923Shibler hildevno(dev) 140953923Shibler dev_t dev; 141053923Shibler { 141153923Shibler int newdev; 141253923Shibler 141353923Shibler newdev = 24 << 24; 141453923Shibler #ifdef HILCOMPAT 141553923Shibler /* 141653923Shibler * XXX compat check 141753923Shibler * Don't convert old style specfiles already in correct format 141853923Shibler */ 141953923Shibler if (minor(dev) && (dev & 0xF) == 0) 142053923Shibler newdev |= minor(dev); 142153923Shibler else 142253923Shibler #endif 142353923Shibler newdev |= (HILLOOP(dev) << 8) | (HILUNIT(dev) << 4); 142453923Shibler return(newdev); 142553923Shibler } 142653923Shibler #endif 142753923Shibler 142853923Shibler /* 142941480Smckusick * Low level routines which actually talk to the 8042 chip. 143041480Smckusick */ 143141480Smckusick 143241480Smckusick /* 143341480Smckusick * Send a command to the 8042 with zero or more bytes of data. 143441480Smckusick * If rdata is non-null, wait for and return a byte of data. 143541480Smckusick * We run at splimp() to make the transaction as atomic as 143641480Smckusick * possible without blocking the clock (is this necessary?) 143741480Smckusick */ 143841480Smckusick send_hil_cmd(hildevice, cmd, data, dlen, rdata) 143941480Smckusick register struct hil_dev *hildevice; 144041480Smckusick u_char cmd, *data, dlen; 144141480Smckusick u_char *rdata; 144241480Smckusick { 144341480Smckusick u_char status; 144441480Smckusick int s = splimp(); 144541480Smckusick 144641480Smckusick HILWAIT(hildevice); 144753923Shibler WRITEHILCMD(hildevice, cmd); 144841480Smckusick while (dlen--) { 144941480Smckusick HILWAIT(hildevice); 145053923Shibler WRITEHILDATA(hildevice, *data++); 145141480Smckusick } 145241480Smckusick if (rdata) { 145341480Smckusick do { 145441480Smckusick HILDATAWAIT(hildevice); 145553923Shibler status = READHILSTAT(hildevice); 145653923Shibler *rdata = READHILDATA(hildevice); 145741480Smckusick } while (((status >> HIL_SSHIFT) & HIL_SMASK) != HIL_68K); 145841480Smckusick } 145941480Smckusick splx(s); 146041480Smckusick } 146141480Smckusick 146241480Smckusick /* 146341480Smckusick * Send a command to a device on the loop. 146441480Smckusick * Since only one command can be active on the loop at any time, 146541480Smckusick * we must ensure that we are not interrupted during this process. 146641480Smckusick * Hence we mask interrupts to prevent potential access from most 146741480Smckusick * interrupt routines and turn off auto-polling to disable the 146841480Smckusick * internally generated poll commands. 146941480Smckusick * 147041480Smckusick * splhigh is extremely conservative but insures atomic operation, 147141480Smckusick * splimp (clock only interrupts) seems to be good enough in practice. 147241480Smckusick */ 147341480Smckusick send_hildev_cmd(hilp, device, cmd) 147441480Smckusick register struct hilloop *hilp; 147541480Smckusick char device, cmd; 147641480Smckusick { 147741480Smckusick register struct hil_dev *hildevice = hilp->hl_addr; 147841480Smckusick u_char status, c; 147941480Smckusick int s = splimp(); 148041480Smckusick 148141480Smckusick polloff(hildevice); 148241480Smckusick 148341480Smckusick /* 148441480Smckusick * Transfer the command and device info to the chip 148541480Smckusick */ 148641480Smckusick HILWAIT(hildevice); 148753923Shibler WRITEHILCMD(hildevice, HIL_STARTCMD); 148841480Smckusick HILWAIT(hildevice); 148953923Shibler WRITEHILDATA(hildevice, 8 + device); 149041480Smckusick HILWAIT(hildevice); 149153923Shibler WRITEHILDATA(hildevice, cmd); 149241480Smckusick HILWAIT(hildevice); 149353923Shibler WRITEHILDATA(hildevice, HIL_TIMEOUT); 149441480Smckusick /* 149541480Smckusick * Trigger the command and wait for completion 149641480Smckusick */ 149741480Smckusick HILWAIT(hildevice); 149853923Shibler WRITEHILCMD(hildevice, HIL_TRIGGER); 149941480Smckusick hilp->hl_cmddone = FALSE; 150041480Smckusick do { 150141480Smckusick HILDATAWAIT(hildevice); 150253923Shibler status = READHILSTAT(hildevice); 150353923Shibler c = READHILDATA(hildevice); 150453923Shibler hil_process_int(hilp, status, c); 150541480Smckusick } while (!hilp->hl_cmddone); 150641480Smckusick 150741480Smckusick pollon(hildevice); 150841480Smckusick splx(s); 150941480Smckusick } 151041480Smckusick 151141480Smckusick /* 151241480Smckusick * Turn auto-polling off and on. 151341480Smckusick * Also disables and enable auto-repeat. Why? 151441480Smckusick */ 151541480Smckusick polloff(hildevice) 151641480Smckusick register struct hil_dev *hildevice; 151741480Smckusick { 151841480Smckusick register char db; 151941480Smckusick 152041480Smckusick /* 152141480Smckusick * Turn off auto repeat 152241480Smckusick */ 152341480Smckusick HILWAIT(hildevice); 152453923Shibler WRITEHILCMD(hildevice, HIL_SETARR); 152541480Smckusick HILWAIT(hildevice); 152653923Shibler WRITEHILDATA(hildevice, 0); 152741480Smckusick /* 152841480Smckusick * Turn off auto-polling 152941480Smckusick */ 153041480Smckusick HILWAIT(hildevice); 153153923Shibler WRITEHILCMD(hildevice, HIL_READLPCTRL); 153241480Smckusick HILDATAWAIT(hildevice); 153353923Shibler db = READHILDATA(hildevice); 153441480Smckusick db &= ~LPC_AUTOPOLL; 153541480Smckusick HILWAIT(hildevice); 153653923Shibler WRITEHILCMD(hildevice, HIL_WRITELPCTRL); 153741480Smckusick HILWAIT(hildevice); 153853923Shibler WRITEHILDATA(hildevice, db); 153941480Smckusick /* 154041480Smckusick * Must wait til polling is really stopped 154141480Smckusick */ 154241480Smckusick do { 154341480Smckusick HILWAIT(hildevice); 154453923Shibler WRITEHILCMD(hildevice, HIL_READBUSY); 154541480Smckusick HILDATAWAIT(hildevice); 154653923Shibler db = READHILDATA(hildevice); 154741480Smckusick } while (db & BSY_LOOPBUSY); 154841480Smckusick } 154941480Smckusick 155041480Smckusick pollon(hildevice) 155141480Smckusick register struct hil_dev *hildevice; 155241480Smckusick { 155341480Smckusick register char db; 155441480Smckusick 155541480Smckusick /* 155641480Smckusick * Turn on auto polling 155741480Smckusick */ 155841480Smckusick HILWAIT(hildevice); 155953923Shibler WRITEHILCMD(hildevice, HIL_READLPCTRL); 156041480Smckusick HILDATAWAIT(hildevice); 156153923Shibler db = READHILDATA(hildevice); 156241480Smckusick db |= LPC_AUTOPOLL; 156341480Smckusick HILWAIT(hildevice); 156453923Shibler WRITEHILCMD(hildevice, HIL_WRITELPCTRL); 156541480Smckusick HILWAIT(hildevice); 156653923Shibler WRITEHILDATA(hildevice, db); 156741480Smckusick /* 156841480Smckusick * Turn on auto repeat 156941480Smckusick */ 157041480Smckusick HILWAIT(hildevice); 157153923Shibler WRITEHILCMD(hildevice, HIL_SETARR); 157241480Smckusick HILWAIT(hildevice); 157353923Shibler WRITEHILDATA(hildevice, ar_format(KBD_ARR)); 157441480Smckusick } 157541480Smckusick 157641480Smckusick #ifdef DEBUG 157741480Smckusick printhilpollbuf(hilp) 157841480Smckusick register struct hilloop *hilp; 157941480Smckusick { 158041480Smckusick register u_char *cp; 158141480Smckusick register int i, len; 158241480Smckusick 158341480Smckusick cp = hilp->hl_pollbuf; 158441480Smckusick len = hilp->hl_pollbp - cp; 158541480Smckusick for (i = 0; i < len; i++) 158641480Smckusick printf("%x ", hilp->hl_pollbuf[i]); 158741480Smckusick printf("\n"); 158841480Smckusick } 158941480Smckusick 159041480Smckusick printhilcmdbuf(hilp) 159141480Smckusick register struct hilloop *hilp; 159241480Smckusick { 159341480Smckusick register u_char *cp; 159441480Smckusick register int i, len; 159541480Smckusick 159641480Smckusick cp = hilp->hl_cmdbuf; 159741480Smckusick len = hilp->hl_cmdbp - cp; 159841480Smckusick for (i = 0; i < len; i++) 159941480Smckusick printf("%x ", hilp->hl_cmdbuf[i]); 160041480Smckusick printf("\n"); 160141480Smckusick } 160241480Smckusick 160341480Smckusick hilreport(hilp) 160441480Smckusick register struct hilloop *hilp; 160541480Smckusick { 160641480Smckusick register int i, len; 160741480Smckusick int s = splhil(); 160841480Smckusick 160941480Smckusick for (i = 1; i <= hilp->hl_maxdev; i++) { 161041480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 161141480Smckusick hilp->hl_cmddev = i; 161241480Smckusick send_hildev_cmd(hilp, i, HILIDENTIFY); 161341480Smckusick printf("hil%d: id: ", i); 161441480Smckusick printhilcmdbuf(hilp); 161541480Smckusick len = hilp->hl_cmdbp - hilp->hl_cmdbuf; 161641480Smckusick if (len > 1 && (hilp->hl_cmdbuf[1] & HILSCBIT)) { 161741480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 161841480Smckusick hilp->hl_cmddev = i; 161941480Smckusick send_hildev_cmd(hilp, i, HILSECURITY); 162041480Smckusick printf("hil%d: sc: ", i); 162141480Smckusick printhilcmdbuf(hilp); 162241480Smckusick } 162341480Smckusick } 162441480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 162541480Smckusick hilp->hl_cmddev = 0; 162641480Smckusick splx(s); 162741480Smckusick } 162841480Smckusick #endif 1629