1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the Systems Programming Group of the University of Utah Computer 8 * Science Department. 9 * 10 * %sccs.include.redist.c% 11 * 12 * from: Utah $Hdr: hil.c 1.33 89/12/22$ 13 * 14 * @(#)hil.c 7.7 (Berkeley) 05/04/91 15 */ 16 17 #include "sys/param.h" 18 #include "sys/conf.h" 19 #include "sys/proc.h" 20 #include "sys/user.h" 21 #include "sys/ioctl.h" 22 #include "sys/file.h" 23 #include "sys/tty.h" 24 #include "sys/systm.h" 25 #include "sys/uio.h" 26 #include "sys/kernel.h" 27 28 #include "hilreg.h" 29 #include "hilioctl.h" 30 #include "hilvar.h" 31 #include "kbdmap.h" 32 33 #include "machine/cpu.h" 34 35 #include "vm/vm_param.h" 36 #include "vm/vm_map.h" 37 #include "vm/vm_kern.h" 38 #include "vm/vm_page.h" 39 #include "vm/vm_pager.h" 40 41 struct hilloop hil0; 42 struct _hilbell default_bell = { BELLDUR, BELLFREQ }; 43 44 #ifdef DEBUG 45 int hildebug = 0; 46 #define HDB_FOLLOW 0x01 47 #define HDB_MMAP 0x02 48 #define HDB_MASK 0x04 49 #define HDB_CONFIG 0x08 50 #define HDB_KEYBOARD 0x10 51 #define HDB_IDMODULE 0x20 52 #define HDB_EVENTS 0x80 53 #endif 54 55 /* symbolic sleep message strings */ 56 char hilin[] = "hilin"; 57 58 hilinit() 59 { 60 register struct hilloop *hilp = &hil0; /* XXX */ 61 register int i; 62 63 /* 64 * Initialize loop information 65 */ 66 hilp->hl_addr = HILADDR; 67 hilp->hl_cmdending = FALSE; 68 hilp->hl_actdev = hilp->hl_cmddev = 0; 69 hilp->hl_cmddone = FALSE; 70 hilp->hl_cmdbp = hilp->hl_cmdbuf; 71 hilp->hl_pollbp = hilp->hl_pollbuf; 72 hilp->hl_kbddev = 0; 73 hilp->hl_kbdlang = KBD_DEFAULT; 74 hilp->hl_kbdflags = 0; 75 /* 76 * Clear all queues and device associations with queues 77 */ 78 for (i = 0; i < NHILQ; i++) { 79 hilp->hl_queue[i].hq_eventqueue = NULL; 80 hilp->hl_queue[i].hq_procp = NULL; 81 hilp->hl_queue[i].hq_devmask = 0; 82 } 83 for (i = 0; i < NHILD; i++) 84 hilp->hl_device[i].hd_qmask = 0; 85 hilp->hl_device[HILLOOPDEV].hd_flags = (HIL_ALIVE|HIL_PSEUDO); 86 /* 87 * Reset the loop hardware, and collect keyboard/id info 88 */ 89 hilreset(hilp); 90 hilinfo(hilp); 91 kbdenable(); 92 } 93 94 /* ARGSUSED */ 95 hilopen(dev, flags, mode, p) 96 dev_t dev; 97 int flags, mode; 98 struct proc *p; 99 { 100 register struct hilloop *hilp = &hil0; /* XXX */ 101 register struct hilloopdev *dptr; 102 u_char device = HILUNIT(dev); 103 104 #ifdef DEBUG 105 if (hildebug & HDB_FOLLOW) 106 printf("hilopen(%d): device %x\n", p->p_pid, device); 107 #endif 108 109 if ((hilp->hl_device[HILLOOPDEV].hd_flags & HIL_ALIVE) == 0) 110 return(ENXIO); 111 112 dptr = &hilp->hl_device[device]; 113 if ((dptr->hd_flags & HIL_ALIVE) == 0) 114 return(ENODEV); 115 116 /* 117 * Pseudo-devices cannot be read, nothing more to do. 118 */ 119 if (dptr->hd_flags & HIL_PSEUDO) 120 return(0); 121 122 /* 123 * Open semantics: 124 * 1. Open devices have only one of HIL_READIN/HIL_QUEUEIN. 125 * 2. HPUX processes always get read syscall interface and 126 * must have exclusive use of the device. 127 * 3. BSD processes default to shared queue interface. 128 * Multiple processes can open the device. 129 */ 130 if (p->p_flag & SHPUX) { 131 if (dptr->hd_flags & (HIL_READIN|HIL_QUEUEIN)) 132 return(EBUSY); 133 dptr->hd_flags |= HIL_READIN; 134 } else { 135 if (dptr->hd_flags & HIL_READIN) 136 return(EBUSY); 137 dptr->hd_flags |= HIL_QUEUEIN; 138 } 139 if (flags & FNDELAY) 140 dptr->hd_flags |= HIL_NOBLOCK; 141 /* 142 * It is safe to flush the read buffer as we are guarenteed 143 * that no one else is using it. 144 */ 145 ndflush(&dptr->hd_queue, dptr->hd_queue.c_cc); 146 147 send_hil_cmd(hilp->hl_addr, HIL_INTON, NULL, 0, NULL); 148 /* 149 * Opened the keyboard, put in raw mode. 150 */ 151 (void) splhil(); 152 if (device == hilp->hl_kbddev) { 153 u_char mask = 0; 154 send_hil_cmd(hilp->hl_addr, HIL_WRITEKBDSADR, &mask, 1, NULL); 155 hilp->hl_kbdflags |= KBD_RAW; 156 #ifdef DEBUG 157 if (hildebug & HDB_KEYBOARD) 158 printf("hilopen: keyboard %d raw\n", hilp->hl_kbddev); 159 #endif 160 } 161 (void) spl0(); 162 return (0); 163 } 164 165 /* ARGSUSED */ 166 hilclose(dev, flags) 167 dev_t dev; 168 { 169 struct proc *p = curproc; /* XXX */ 170 register struct hilloop *hilp = &hil0; /* XXX */ 171 register struct hilloopdev *dptr; 172 register int i; 173 u_char device = HILUNIT(dev); 174 char mask, lpctrl; 175 176 #ifdef DEBUG 177 if (hildebug & HDB_FOLLOW) 178 printf("hilclose(%d): device %x\n", p->p_pid, device); 179 #endif 180 181 dptr = &hilp->hl_device[device]; 182 if (device && (dptr->hd_flags & HIL_PSEUDO)) 183 return (0); 184 185 if ((p->p_flag & SHPUX) == 0) { 186 /* 187 * If this is the loop device, 188 * free up all queues belonging to this process. 189 */ 190 if (device == 0) { 191 for (i = 0; i < NHILQ; i++) 192 if (hilp->hl_queue[i].hq_procp == p) 193 (void) hilqfree(i); 194 } else { 195 mask = ~hildevmask(device); 196 (void) splhil(); 197 for (i = 0; i < NHILQ; i++) 198 if (hilp->hl_queue[i].hq_procp == p) { 199 dptr->hd_qmask &= ~hilqmask(i); 200 hilp->hl_queue[i].hq_devmask &= mask; 201 } 202 (void) spl0(); 203 } 204 } 205 /* 206 * Always flush the read buffer 207 */ 208 dptr->hd_flags &= ~(HIL_QUEUEIN|HIL_READIN|HIL_NOBLOCK); 209 ndflush(&dptr->hd_queue, dptr->hd_queue.c_cc); 210 /* 211 * Set keyboard back to cooked mode when closed. 212 */ 213 (void) splhil(); 214 if (device && device == hilp->hl_kbddev) { 215 mask = 1 << (hilp->hl_kbddev - 1); 216 send_hil_cmd(hilp->hl_addr, HIL_WRITEKBDSADR, &mask, 1, NULL); 217 hilp->hl_kbdflags &= ~(KBD_RAW|KBD_AR1|KBD_AR2); 218 /* 219 * XXX: We have had trouble with keyboards remaining raw 220 * after close due to the LPC_KBDCOOK bit getting cleared 221 * somewhere along the line. Hence we check and reset 222 * LPCTRL if necessary. 223 */ 224 send_hil_cmd(hilp->hl_addr, HIL_READLPCTRL, NULL, 0, &lpctrl); 225 if ((lpctrl & LPC_KBDCOOK) == 0) { 226 printf("hilclose: bad LPCTRL %x, reset to %x\n", 227 lpctrl, lpctrl|LPC_KBDCOOK); 228 lpctrl |= LPC_KBDCOOK; 229 send_hil_cmd(hilp->hl_addr, HIL_WRITELPCTRL, 230 &lpctrl, 1, NULL); 231 } 232 #ifdef DEBUG 233 if (hildebug & HDB_KEYBOARD) 234 printf("hilclose: keyboard %d cooked\n", 235 hilp->hl_kbddev); 236 #endif 237 kbdenable(); 238 } 239 (void) spl0(); 240 return (0); 241 } 242 243 /* 244 * Read interface to HIL device. 245 */ 246 hilread(dev, uio) 247 dev_t dev; 248 register struct uio *uio; 249 { 250 struct hilloop *hilp = &hil0; /* XXX */ 251 register struct hilloopdev *dptr; 252 register int cc; 253 u_char device = HILUNIT(dev); 254 char buf[HILBUFSIZE]; 255 int error; 256 257 #if 0 258 /* 259 * XXX: Don't do this since HP-UX doesn't. 260 * 261 * Check device number. 262 * This check is necessary since loop can reconfigure. 263 */ 264 if (device > hilp->hl_maxdev) 265 return(ENODEV); 266 #endif 267 268 dptr = &hilp->hl_device[device]; 269 if ((dptr->hd_flags & HIL_READIN) == 0) 270 return(ENODEV); 271 272 (void) splhil(); 273 while (dptr->hd_queue.c_cc == 0) { 274 if (dptr->hd_flags & HIL_NOBLOCK) { 275 spl0(); 276 return(EWOULDBLOCK); 277 } 278 dptr->hd_flags |= HIL_ASLEEP; 279 if (error = tsleep((caddr_t)dptr, TTIPRI | PCATCH, hilin, 0)) { 280 (void) spl0(); 281 return (error); 282 } 283 } 284 (void) spl0(); 285 286 error = 0; 287 while (uio->uio_resid > 0 && error == 0) { 288 cc = hilq_to_b(&dptr->hd_queue, buf, 289 MIN(uio->uio_resid, HILBUFSIZE)); 290 if (cc <= 0) 291 break; 292 error = uiomove(buf, cc, uio); 293 } 294 return(error); 295 } 296 297 hilioctl(dev, cmd, data, flag, p) 298 dev_t dev; 299 caddr_t data; 300 struct proc *p; 301 { 302 register struct hilloop *hilp = &hil0; /* XXX */ 303 char device = HILUNIT(dev); 304 struct hilloopdev *dptr; 305 register int i; 306 u_char hold; 307 int error; 308 309 #ifdef DEBUG 310 if (hildebug & HDB_FOLLOW) 311 printf("hilioctl(%d): dev %x cmd %x\n", 312 p->p_pid, device, cmd); 313 #endif 314 315 dptr = &hilp->hl_device[device]; 316 if ((dptr->hd_flags & HIL_ALIVE) == 0) 317 return (ENODEV); 318 319 /* 320 * Don't allow hardware ioctls on virtual devices. 321 * Note that though these are the BSD names, they have the same 322 * values as the HP-UX equivalents so we catch them as well. 323 */ 324 if (dptr->hd_flags & HIL_PSEUDO) { 325 switch (cmd) { 326 case HILIOCSC: 327 case HILIOCID: 328 case HILIOCRN: 329 case HILIOCRS: 330 case HILIOCED: 331 return(ENODEV); 332 333 /* 334 * XXX: should also return ENODEV but HP-UX compat 335 * breaks if we do. They work ok right now because 336 * we only recognize one keyboard on the loop. This 337 * will have to change if we remove that restriction. 338 */ 339 case HILIOCAROFF: 340 case HILIOCAR1: 341 case HILIOCAR2: 342 break; 343 344 default: 345 break; 346 } 347 } 348 349 #ifdef HPUXCOMPAT 350 if (p->p_flag & SHPUX) 351 return(hpuxhilioctl(dev, cmd, data, flag)); 352 #endif 353 354 hilp->hl_cmdbp = hilp->hl_cmdbuf; 355 bzero((caddr_t)hilp->hl_cmdbuf, HILBUFSIZE); 356 hilp->hl_cmddev = device; 357 error = 0; 358 switch (cmd) { 359 360 case HILIOCSBP: 361 /* Send four data bytes to the tone gererator. */ 362 send_hil_cmd(hilp->hl_addr, HIL_STARTCMD, data, 4, NULL); 363 /* Send the trigger beeper command to the 8042. */ 364 send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL); 365 break; 366 367 case HILIOCRRT: 368 /* Transfer the real time to the 8042 data buffer */ 369 send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL); 370 /* Read each byte of the real time */ 371 for (i = 0; i < 5; i++) { 372 send_hil_cmd(hilp->hl_addr, HIL_READTIME + i, NULL, 373 0, &hold); 374 data[4-i] = hold; 375 } 376 break; 377 378 case HILIOCRT: 379 for (i = 0; i < 4; i++) { 380 send_hil_cmd(hilp->hl_addr, (cmd & 0xFF) + i, 381 NULL, 0, &hold); 382 data[i] = hold; 383 } 384 break; 385 386 case HILIOCID: 387 case HILIOCSC: 388 case HILIOCRN: 389 case HILIOCRS: 390 case HILIOCED: 391 send_hildev_cmd(hilp, device, (cmd & 0xFF)); 392 bcopy(hilp->hl_cmdbuf, data, hilp->hl_cmdbp-hilp->hl_cmdbuf); 393 break; 394 395 case HILIOCAROFF: 396 case HILIOCAR1: 397 case HILIOCAR2: 398 if (hilp->hl_kbddev) { 399 hilp->hl_cmddev = hilp->hl_kbddev; 400 send_hildev_cmd(hilp, hilp->hl_kbddev, (cmd & 0xFF)); 401 hilp->hl_kbdflags &= ~(KBD_AR1|KBD_AR2); 402 if (cmd == HILIOCAR1) 403 hilp->hl_kbdflags |= KBD_AR1; 404 else if (cmd == HILIOCAR2) 405 hilp->hl_kbdflags |= KBD_AR2; 406 } 407 break; 408 409 case HILIOCBEEP: 410 hilbeep(hilp, (struct _hilbell *)data); 411 break; 412 413 case FIONBIO: 414 dptr = &hilp->hl_device[device]; 415 if (*(int *)data) 416 dptr->hd_flags |= HIL_NOBLOCK; 417 else 418 dptr->hd_flags &= ~HIL_NOBLOCK; 419 break; 420 421 /* 422 * FIOASYNC must be present for FIONBIO above to work! 423 * (See fcntl in kern_descrip.c). 424 */ 425 case FIOASYNC: 426 break; 427 428 case HILIOCALLOCQ: 429 error = hilqalloc((struct hilqinfo *)data); 430 break; 431 432 case HILIOCFREEQ: 433 error = hilqfree(((struct hilqinfo *)data)->qid); 434 break; 435 436 case HILIOCMAPQ: 437 error = hilqmap(*(int *)data, device); 438 break; 439 440 case HILIOCUNMAPQ: 441 error = hilqunmap(*(int *)data, device); 442 break; 443 444 case HILIOCHPUX: 445 dptr = &hilp->hl_device[device]; 446 dptr->hd_flags |= HIL_READIN; 447 dptr->hd_flags &= ~HIL_QUEUEIN; 448 break; 449 450 case HILIOCRESET: 451 hilreset(hilp); 452 break; 453 454 #ifdef DEBUG 455 case HILIOCTEST: 456 hildebug = *(int *) data; 457 break; 458 #endif 459 460 default: 461 error = EINVAL; 462 break; 463 464 } 465 hilp->hl_cmddev = 0; 466 return(error); 467 } 468 469 #ifdef HPUXCOMPAT 470 /* ARGSUSED */ 471 hpuxhilioctl(dev, cmd, data, flag) 472 dev_t dev; 473 caddr_t data; 474 { 475 register struct hilloop *hilp = &hil0; /* XXX */ 476 char device = HILUNIT(dev); 477 struct hilloopdev *dptr; 478 register int i; 479 u_char hold; 480 481 hilp->hl_cmdbp = hilp->hl_cmdbuf; 482 bzero((caddr_t)hilp->hl_cmdbuf, HILBUFSIZE); 483 hilp->hl_cmddev = device; 484 switch (cmd) { 485 486 case HILSC: 487 case HILID: 488 case HILRN: 489 case HILRS: 490 case HILED: 491 case HILP1: 492 case HILP2: 493 case HILP3: 494 case HILP4: 495 case HILP5: 496 case HILP6: 497 case HILP7: 498 case HILP: 499 case HILA1: 500 case HILA2: 501 case HILA3: 502 case HILA4: 503 case HILA5: 504 case HILA6: 505 case HILA7: 506 case HILA: 507 send_hildev_cmd(hilp, device, (cmd & 0xFF)); 508 bcopy(hilp->hl_cmdbuf, data, hilp->hl_cmdbp-hilp->hl_cmdbuf); 509 break; 510 511 case HILDKR: 512 case HILER1: 513 case HILER2: 514 if (hilp->hl_kbddev) { 515 hilp->hl_cmddev = hilp->hl_kbddev; 516 send_hildev_cmd(hilp, hilp->hl_kbddev, (cmd & 0xFF)); 517 hilp->hl_kbdflags &= ~(KBD_AR1|KBD_AR2); 518 if (cmd == HILIOCAR1) 519 hilp->hl_kbdflags |= KBD_AR1; 520 else if (cmd == HILIOCAR2) 521 hilp->hl_kbdflags |= KBD_AR2; 522 } 523 break; 524 525 case EFTSBP: 526 /* Send four data bytes to the tone gererator. */ 527 send_hil_cmd(hilp->hl_addr, HIL_STARTCMD, data, 4, NULL); 528 /* Send the trigger beeper command to the 8042. */ 529 send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL); 530 break; 531 532 case EFTRRT: 533 /* Transfer the real time to the 8042 data buffer */ 534 send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL); 535 /* Read each byte of the real time */ 536 for (i = 0; i < 5; i++) { 537 send_hil_cmd(hilp->hl_addr, HIL_READTIME + i, NULL, 538 0, &hold); 539 data[4-i] = hold; 540 } 541 break; 542 543 case EFTRT: 544 for (i = 0; i < 4; i++) { 545 send_hil_cmd(hilp->hl_addr, (cmd & 0xFF) + i, 546 NULL, 0, &hold); 547 data[i] = hold; 548 } 549 break; 550 551 case EFTRLC: 552 case EFTRCC: 553 send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, &hold); 554 *data = hold; 555 break; 556 557 case EFTSRPG: 558 case EFTSRD: 559 case EFTSRR: 560 send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), data, 1, NULL); 561 break; 562 563 case EFTSBI: 564 hilbeep(hilp, (struct _hilbell *)data); 565 break; 566 567 case FIONBIO: 568 dptr = &hilp->hl_device[device]; 569 if (*(int *)data) 570 dptr->hd_flags |= HIL_NOBLOCK; 571 else 572 dptr->hd_flags &= ~HIL_NOBLOCK; 573 break; 574 575 case FIOASYNC: 576 break; 577 578 default: 579 hilp->hl_cmddev = 0; 580 return(EINVAL); 581 } 582 hilp->hl_cmddev = 0; 583 return(0); 584 } 585 #endif 586 587 /* 588 * XXX: the mmap interface for HIL devices should be rethought. 589 * We used it only briefly in conjuntion with shared queues 590 * (instead of HILIOCMAPQ ioctl). Perhaps mmap()ing a device 591 * should give a single queue per process. 592 */ 593 /* ARGSUSED */ 594 hilmap(dev, off, prot) 595 dev_t dev; 596 register int off; 597 { 598 #ifdef MMAP 599 struct proc *p = curproc; /* XXX */ 600 register struct hilloop *hilp = &hil0; /* XXX */ 601 register struct hiliqueue *qp; 602 register int qnum; 603 604 /* 605 * Only allow mmap() on loop device 606 */ 607 if (HILUNIT(dev) != 0 || off >= NHILQ*sizeof(HILQ)) 608 return(-1); 609 /* 610 * Determine which queue we want based on the offset. 611 * Queue must belong to calling process. 612 */ 613 qp = &hilp->hl_queue[off / sizeof(HILQ)]; 614 if (qp->hq_procp != p) 615 return(-1); 616 617 off %= sizeof(HILQ); 618 return(kvtop((u_int)qp->hq_eventqueue + off) >> PGSHIFT); 619 #endif 620 } 621 622 /*ARGSUSED*/ 623 hilselect(dev, rw, p) 624 dev_t dev; 625 struct proc *p; 626 { 627 register struct hilloop *hilp = &hil0; /* XXX */ 628 register struct hilloopdev *dptr; 629 register struct hiliqueue *qp; 630 register int mask; 631 int s, device; 632 633 if (rw == FWRITE) 634 return (1); 635 device = HILUNIT(dev); 636 637 /* 638 * Read interface. 639 * Return 1 if there is something in the queue, 0 ow. 640 */ 641 dptr = &hilp->hl_device[device]; 642 if (dptr->hd_flags & HIL_READIN) { 643 s = splhil(); 644 if (dptr->hd_queue.c_cc) { 645 splx(s); 646 return (1); 647 } 648 if (dptr->hd_selr && 649 dptr->hd_selr->p_wchan == (caddr_t)&selwait) 650 dptr->hd_flags |= HIL_SELCOLL; 651 else 652 dptr->hd_selr = p; 653 splx(s); 654 return (0); 655 } 656 657 /* 658 * Make sure device is alive and real (or the loop device). 659 * Note that we do not do this for the read interface. 660 * This is primarily to be consistant with HP-UX. 661 */ 662 if (device && (dptr->hd_flags & (HIL_ALIVE|HIL_PSEUDO)) != HIL_ALIVE) 663 return (1); 664 665 /* 666 * Select on loop device is special. 667 * Check to see if there are any data for any loop device 668 * provided it is associated with a queue belonging to this user. 669 */ 670 if (device == 0) 671 mask = -1; 672 else 673 mask = hildevmask(device); 674 /* 675 * Must check everybody with interrupts blocked to prevent races. 676 */ 677 s = splhil(); 678 for (qp = hilp->hl_queue; qp < &hilp->hl_queue[NHILQ]; qp++) 679 if (qp->hq_procp == p && (mask & qp->hq_devmask) && 680 qp->hq_eventqueue->hil_evqueue.head != 681 qp->hq_eventqueue->hil_evqueue.tail) { 682 splx(s); 683 return (1); 684 } 685 686 if (dptr->hd_selr && dptr->hd_selr->p_wchan == (caddr_t)&selwait) 687 dptr->hd_flags |= HIL_SELCOLL; 688 else 689 dptr->hd_selr = p; 690 splx(s); 691 return (0); 692 } 693 694 hilint() 695 { 696 struct hilloop *hilp = &hil0; /* XXX */ 697 register struct hil_dev *hildevice = hilp->hl_addr; 698 u_char c, stat; 699 700 stat = hildevice->hil_stat; 701 c = hildevice->hil_data; /* clears interrupt */ 702 hil_process_int(stat, c); 703 } 704 705 #include "ite.h" 706 707 hil_process_int(stat, c) 708 register u_char stat, c; 709 { 710 register struct hilloop *hilp; 711 712 #ifdef DEBUG 713 if (hildebug & HDB_EVENTS) 714 printf("hilint: %x %x\n", stat, c); 715 #endif 716 717 /* the shift enables the compiler to generate a jump table */ 718 switch ((stat>>HIL_SSHIFT) & HIL_SMASK) { 719 720 #if NITE > 0 721 case HIL_KEY: 722 case HIL_SHIFT: 723 case HIL_CTRL: 724 case HIL_CTRLSHIFT: 725 itefilter(stat, c); 726 return; 727 #endif 728 729 case HIL_STATUS: /* The status info. */ 730 hilp = &hil0; /* XXX */ 731 if (c & HIL_ERROR) { 732 hilp->hl_cmddone = TRUE; 733 if (c == HIL_RECONFIG) 734 hilconfig(hilp); 735 break; 736 } 737 if (c & HIL_COMMAND) { 738 if (c & HIL_POLLDATA) /* End of data */ 739 hilevent(hilp); 740 else /* End of command */ 741 hilp->hl_cmdending = TRUE; 742 hilp->hl_actdev = 0; 743 } else { 744 if (c & HIL_POLLDATA) { /* Start of polled data */ 745 if (hilp->hl_actdev != 0) 746 hilevent(hilp); 747 hilp->hl_actdev = (c & HIL_DEVMASK); 748 hilp->hl_pollbp = hilp->hl_pollbuf; 749 } else { /* Start of command */ 750 if (hilp->hl_cmddev == (c & HIL_DEVMASK)) { 751 hilp->hl_cmdbp = hilp->hl_cmdbuf; 752 hilp->hl_actdev = 0; 753 } 754 } 755 } 756 return; 757 758 case HIL_DATA: 759 hilp = &hil0; /* XXX */ 760 if (hilp->hl_actdev != 0) /* Collecting poll data */ 761 *hilp->hl_pollbp++ = c; 762 else if (hilp->hl_cmddev != 0) /* Collecting cmd data */ 763 if (hilp->hl_cmdending) { 764 hilp->hl_cmddone = TRUE; 765 hilp->hl_cmdending = FALSE; 766 } else 767 *hilp->hl_cmdbp++ = c; 768 return; 769 770 case 0: /* force full jump table */ 771 default: 772 return; 773 } 774 } 775 776 #if defined(DEBUG) && !defined(PANICBUTTON) 777 #define PANICBUTTON 778 #endif 779 780 /* 781 * Optimized macro to compute: 782 * eq->head == (eq->tail + 1) % eq->size 783 * i.e. has tail caught up with head. We do this because 32 bit long 784 * remaidering is expensive (a function call with our compiler). 785 */ 786 #define HQFULL(eq) (((eq)->head?(eq)->head:(eq)->size) == (eq)->tail+1) 787 #define HQVALID(eq) \ 788 ((eq)->size == HEVQSIZE && (eq)->tail >= 0 && (eq)->tail < HEVQSIZE) 789 790 hilevent(hilp) 791 struct hilloop *hilp; 792 { 793 register struct hilloopdev *dptr = &hilp->hl_device[hilp->hl_actdev]; 794 register int len, mask, qnum; 795 register u_char *cp, *pp; 796 register HILQ *hq; 797 struct timeval ourtime; 798 hil_packet *proto; 799 int s, len0; 800 long tenths; 801 802 #ifdef PANICBUTTON 803 static int first; 804 extern int panicbutton; 805 806 cp = hilp->hl_pollbuf; 807 if (panicbutton && (*cp & HIL_KBDDATA)) { 808 if (*++cp == 0x4E) 809 first = 1; 810 else if (first && *cp == 0x46 && !panicstr) 811 panic("are we having fun yet?"); 812 else 813 first = 0; 814 } 815 #endif 816 #ifdef DEBUG 817 if (hildebug & HDB_EVENTS) { 818 printf("hilevent: dev %d pollbuf: ", hilp->hl_actdev); 819 printhilpollbuf(hilp); 820 printf("\n"); 821 } 822 #endif 823 824 /* 825 * Note that HIL_READIN effectively "shuts off" any queues 826 * that may have been in use at the time of an HILIOCHPUX call. 827 */ 828 if (dptr->hd_flags & HIL_READIN) { 829 hpuxhilevent(hilp, dptr); 830 return; 831 } 832 833 /* 834 * If this device isn't on any queue or there are no data 835 * in the packet (can this happen?) do nothing. 836 */ 837 if (dptr->hd_qmask == 0 || 838 (len0 = hilp->hl_pollbp - hilp->hl_pollbuf) <= 0) 839 return; 840 841 /* 842 * Everybody gets the same time stamp 843 */ 844 s = splclock(); 845 ourtime = time; 846 splx(s); 847 tenths = (ourtime.tv_sec * 100) + (ourtime.tv_usec / 10000); 848 849 proto = NULL; 850 mask = dptr->hd_qmask; 851 for (qnum = 0; mask; qnum++) { 852 if ((mask & hilqmask(qnum)) == 0) 853 continue; 854 mask &= ~hilqmask(qnum); 855 hq = hilp->hl_queue[qnum].hq_eventqueue; 856 857 /* 858 * Ensure that queue fields that we rely on are valid 859 * and that there is space in the queue. If either 860 * test fails, we just skip this queue. 861 */ 862 if (!HQVALID(&hq->hil_evqueue) || HQFULL(&hq->hil_evqueue)) 863 continue; 864 865 /* 866 * Copy data to queue. 867 * If this is the first queue we construct the packet 868 * with length, timestamp and poll buffer data. 869 * For second and sucessive packets we just duplicate 870 * the first packet. 871 */ 872 pp = (u_char *) &hq->hil_event[hq->hil_evqueue.tail]; 873 if (proto == NULL) { 874 proto = (hil_packet *)pp; 875 cp = hilp->hl_pollbuf; 876 len = len0; 877 *pp++ = len + 6; 878 *pp++ = hilp->hl_actdev; 879 *(long *)pp = tenths; 880 pp += sizeof(long); 881 do *pp++ = *cp++; while (--len); 882 } else 883 *(hil_packet *)pp = *proto; 884 885 if (++hq->hil_evqueue.tail == hq->hil_evqueue.size) 886 hq->hil_evqueue.tail = 0; 887 } 888 889 /* 890 * Wake up anyone selecting on this device or the loop itself 891 */ 892 if (dptr->hd_selr) { 893 selwakeup(dptr->hd_selr, dptr->hd_flags & HIL_SELCOLL); 894 dptr->hd_selr = NULL; 895 dptr->hd_flags &= ~HIL_SELCOLL; 896 } 897 dptr = &hilp->hl_device[HILLOOPDEV]; 898 if (dptr->hd_selr) { 899 selwakeup(dptr->hd_selr, dptr->hd_flags & HIL_SELCOLL); 900 dptr->hd_selr = NULL; 901 dptr->hd_flags &= ~HIL_SELCOLL; 902 } 903 } 904 905 #undef HQFULL 906 907 hpuxhilevent(hilp, dptr) 908 register struct hilloop *hilp; 909 register struct hilloopdev *dptr; 910 { 911 register int len; 912 struct timeval ourtime; 913 long tstamp; 914 int s; 915 916 /* 917 * Everybody gets the same time stamp 918 */ 919 s = splclock(); 920 ourtime = time; 921 splx(s); 922 tstamp = (ourtime.tv_sec * 100) + (ourtime.tv_usec / 10000); 923 924 /* 925 * Each packet that goes into the buffer must be preceded by the 926 * number of bytes in the packet, and the timestamp of the packet. 927 * This adds 5 bytes to the packet size. Make sure there is enough 928 * room in the buffer for it, and if not, toss the packet. 929 */ 930 len = hilp->hl_pollbp - hilp->hl_pollbuf; 931 if (dptr->hd_queue.c_cc <= (HILMAXCLIST - (len+5))) { 932 putc(len+5, &dptr->hd_queue); 933 (void) b_to_q((char *)&tstamp, sizeof tstamp, &dptr->hd_queue); 934 (void) b_to_q((char *)hilp->hl_pollbuf, len, &dptr->hd_queue); 935 } 936 937 /* 938 * Wake up any one blocked on a read or select 939 */ 940 if (dptr->hd_flags & HIL_ASLEEP) { 941 dptr->hd_flags &= ~HIL_ASLEEP; 942 wakeup((caddr_t)dptr); 943 } 944 if (dptr->hd_selr) { 945 selwakeup(dptr->hd_selr, dptr->hd_flags & HIL_SELCOLL); 946 dptr->hd_selr = NULL; 947 dptr->hd_flags &= ~HIL_SELCOLL; 948 } 949 } 950 951 /* 952 * Shared queue manipulation routines 953 */ 954 955 hilqalloc(qip) 956 struct hilqinfo *qip; 957 { 958 struct proc *p = curproc; /* XXX */ 959 960 #ifdef DEBUG 961 if (hildebug & HDB_FOLLOW) 962 printf("hilqalloc(%d): addr %x\n", p->p_pid, qip->addr); 963 #endif 964 return(EINVAL); 965 } 966 967 hilqfree(qnum) 968 register int qnum; 969 { 970 struct proc *p = curproc; /* XXX */ 971 972 #ifdef DEBUG 973 if (hildebug & HDB_FOLLOW) 974 printf("hilqfree(%d): qnum %d\n", p->p_pid, qnum); 975 #endif 976 return(EINVAL); 977 } 978 979 hilqmap(qnum, device) 980 register int qnum, device; 981 { 982 struct proc *p = curproc; /* XXX */ 983 register struct hilloop *hilp = &hil0; /* XXX */ 984 register struct hilloopdev *dptr = &hilp->hl_device[device]; 985 int s; 986 987 #ifdef DEBUG 988 if (hildebug & HDB_FOLLOW) 989 printf("hilqmap(%d): qnum %d device %x\n", 990 p->p_pid, qnum, device); 991 #endif 992 if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p) 993 return(EINVAL); 994 if ((dptr->hd_flags & HIL_QUEUEIN) == 0) 995 return(EINVAL); 996 if (dptr->hd_qmask && p->p_ucred->cr_uid && 997 p->p_ucred->cr_uid != dptr->hd_uid) 998 return(EPERM); 999 1000 hilp->hl_queue[qnum].hq_devmask |= hildevmask(device); 1001 if (dptr->hd_qmask == 0) 1002 dptr->hd_uid = p->p_ucred->cr_uid; 1003 s = splhil(); 1004 dptr->hd_qmask |= hilqmask(qnum); 1005 splx(s); 1006 #ifdef DEBUG 1007 if (hildebug & HDB_MASK) 1008 printf("hilqmap(%d): devmask %x qmask %x\n", 1009 p->p_pid, hilp->hl_queue[qnum].hq_devmask, 1010 dptr->hd_qmask); 1011 #endif 1012 return(0); 1013 } 1014 1015 hilqunmap(qnum, device) 1016 register int qnum, device; 1017 { 1018 struct proc *p = curproc; /* XXX */ 1019 register struct hilloop *hilp = &hil0; /* XXX */ 1020 int s; 1021 1022 #ifdef DEBUG 1023 if (hildebug & HDB_FOLLOW) 1024 printf("hilqunmap(%d): qnum %d device %x\n", 1025 p->p_pid, qnum, device); 1026 #endif 1027 1028 if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p) 1029 return(EINVAL); 1030 1031 hilp->hl_queue[qnum].hq_devmask &= ~hildevmask(device); 1032 s = splhil(); 1033 hilp->hl_device[device].hd_qmask &= ~hilqmask(qnum); 1034 splx(s); 1035 #ifdef DEBUG 1036 if (hildebug & HDB_MASK) 1037 printf("hilqunmap(%d): devmask %x qmask %x\n", 1038 p->p_pid, hilp->hl_queue[qnum].hq_devmask, 1039 hilp->hl_device[device].hd_qmask); 1040 #endif 1041 return(0); 1042 } 1043 1044 #include "sys/clist.h" 1045 1046 /* 1047 * This is just a copy of the virgin q_to_b routine with minor 1048 * optimizations for HIL use. It is used for two reasons: 1049 * 1. If we have PAGE mode defined, the normal q_to_b processes 1050 * chars one at a time and breaks on newlines. 1051 * 2. We don't have to raise the priority to spltty() for most 1052 * of the clist manipulations. 1053 */ 1054 hilq_to_b(q, cp, cc) 1055 register struct clist *q; 1056 register char *cp; 1057 { 1058 register struct cblock *bp; 1059 register int nc; 1060 char *acp; 1061 int s; 1062 extern char cwaiting; 1063 1064 if (cc <= 0) 1065 return (0); 1066 s = splhil(); 1067 if (q->c_cc <= 0) { 1068 q->c_cc = 0; 1069 q->c_cf = q->c_cl = NULL; 1070 splx(s); 1071 return (0); 1072 } 1073 acp = cp; 1074 1075 while (cc) { 1076 nc = sizeof (struct cblock) - ((int)q->c_cf & CROUND); 1077 nc = MIN(nc, cc); 1078 nc = MIN(nc, q->c_cc); 1079 (void) bcopy(q->c_cf, cp, (unsigned)nc); 1080 q->c_cf += nc; 1081 q->c_cc -= nc; 1082 cc -= nc; 1083 cp += nc; 1084 if (q->c_cc <= 0) { 1085 bp = (struct cblock *)(q->c_cf - 1); 1086 bp = (struct cblock *)((int)bp & ~CROUND); 1087 q->c_cf = q->c_cl = NULL; 1088 spltty(); 1089 bp->c_next = cfreelist; 1090 cfreelist = bp; 1091 cfreecount += CBSIZE; 1092 if (cwaiting) { 1093 wakeup(&cwaiting); 1094 cwaiting = 0; 1095 } 1096 break; 1097 } 1098 if (((int)q->c_cf & CROUND) == 0) { 1099 bp = (struct cblock *)(q->c_cf); 1100 bp--; 1101 q->c_cf = bp->c_next->c_info; 1102 spltty(); 1103 bp->c_next = cfreelist; 1104 cfreelist = bp; 1105 cfreecount += CBSIZE; 1106 if (cwaiting) { 1107 wakeup(&cwaiting); 1108 cwaiting = 0; 1109 } 1110 splhil(); 1111 } 1112 } 1113 splx(s); 1114 return (cp-acp); 1115 } 1116 1117 /* 1118 * Cooked keyboard functions for ite driver. 1119 * There is only one "cooked" ITE keyboard (the first keyboard found) 1120 * per loop. There may be other keyboards, but they will always be "raw". 1121 */ 1122 1123 kbdbell() 1124 { 1125 struct hilloop *hilp = &hil0; /* XXX */ 1126 1127 hilbeep(hilp, &default_bell); 1128 } 1129 1130 kbdenable() 1131 { 1132 struct hilloop *hilp = &hil0; /* XXX */ 1133 register struct hil_dev *hildevice = hilp->hl_addr; 1134 char db; 1135 1136 /* Set the autorepeat rate register */ 1137 db = ar_format(KBD_ARR); 1138 send_hil_cmd(hildevice, HIL_SETARR, &db, 1, NULL); 1139 1140 /* Set the autorepeat delay register */ 1141 db = ar_format(KBD_ARD); 1142 send_hil_cmd(hildevice, HIL_SETARD, &db, 1, NULL); 1143 1144 /* Enable interrupts */ 1145 send_hil_cmd(hildevice, HIL_INTON, NULL, 0, NULL); 1146 } 1147 1148 kbddisable() 1149 { 1150 } 1151 1152 /* 1153 * XXX: read keyboard directly and return code. 1154 * Used by console getchar routine. Could really screw up anybody 1155 * reading from the keyboard in the normal, interrupt driven fashion. 1156 */ 1157 kbdgetc(statp) 1158 int *statp; 1159 { 1160 struct hilloop *hilp = &hil0; /* XXX */ 1161 register struct hil_dev *hildevice = hilp->hl_addr; 1162 register int c, stat; 1163 int s; 1164 1165 s = splhil(); 1166 while (((stat = hildevice->hil_stat) & HIL_DATA_RDY) == 0) 1167 ; 1168 c = hildevice->hil_data; 1169 splx(s); 1170 *statp = stat; 1171 return(c); 1172 } 1173 1174 /* 1175 * Recoginize and clear keyboard generated NMIs. 1176 * Returns 1 if it was ours, 0 otherwise. Note that we cannot use 1177 * send_hil_cmd() to issue the clear NMI command as that would actually 1178 * lower the priority to splimp() and it doesn't wait for the completion 1179 * of the command. Either of these conditions could result in the 1180 * interrupt reoccuring. Note that we issue the CNMT command twice. 1181 * This seems to be needed, once is not always enough!?! 1182 */ 1183 kbdnmi() 1184 { 1185 register struct hilloop *hilp = &hil0; /* XXX */ 1186 1187 if ((*KBDNMISTAT & KBDNMI) == 0) 1188 return(0); 1189 HILWAIT(hilp->hl_addr); 1190 hilp->hl_addr->hil_cmd = HIL_CNMT; 1191 HILWAIT(hilp->hl_addr); 1192 hilp->hl_addr->hil_cmd = HIL_CNMT; 1193 HILWAIT(hilp->hl_addr); 1194 return(1); 1195 } 1196 1197 #define HILSECURITY 0x33 1198 #define HILIDENTIFY 0x03 1199 #define HILSCBIT 0x04 1200 1201 /* 1202 * Called at boot time to print out info about interesting devices 1203 */ 1204 hilinfo(hilp) 1205 register struct hilloop *hilp; 1206 { 1207 register int id, len; 1208 register struct kbdmap *km; 1209 1210 /* 1211 * Keyboard info. 1212 */ 1213 if (hilp->hl_kbddev) { 1214 printf("hil%d: ", hilp->hl_kbddev); 1215 for (km = kbd_map; km->kbd_code; km++) 1216 if (km->kbd_code == hilp->hl_kbdlang) { 1217 printf("%s ", km->kbd_desc); 1218 break; 1219 } 1220 printf("keyboard\n"); 1221 } 1222 /* 1223 * ID module. 1224 * Attempt to locate the first ID module and print out its 1225 * security code. Is this a good idea?? 1226 */ 1227 id = hiliddev(hilp); 1228 if (id) { 1229 hilp->hl_cmdbp = hilp->hl_cmdbuf; 1230 hilp->hl_cmddev = id; 1231 send_hildev_cmd(hilp, id, HILSECURITY); 1232 len = hilp->hl_cmdbp - hilp->hl_cmdbuf; 1233 hilp->hl_cmdbp = hilp->hl_cmdbuf; 1234 hilp->hl_cmddev = 0; 1235 printf("hil%d: security code", id); 1236 for (id = 0; id < len; id++) 1237 printf(" %x", hilp->hl_cmdbuf[id]); 1238 while (id++ < 16) 1239 printf(" 0"); 1240 printf("\n"); 1241 } 1242 } 1243 1244 #define HILAR1 0x3E 1245 #define HILAR2 0x3F 1246 1247 /* 1248 * Called after the loop has reconfigured. Here we need to: 1249 * - determine how many devices are on the loop 1250 * (some may have been added or removed) 1251 * - locate the ITE keyboard (if any) and ensure 1252 * that it is in the proper state (raw or cooked) 1253 * and is set to use the proper language mapping table 1254 * - ensure all other keyboards are raw 1255 * Note that our device state is now potentially invalid as 1256 * devices may no longer be where they were. What we should 1257 * do here is either track where the devices went and move 1258 * state around accordingly or, more simply, just mark all 1259 * devices as HIL_DERROR and don't allow any further use until 1260 * they are closed. This is a little too brutal for my tastes, 1261 * we prefer to just assume people won't move things around. 1262 */ 1263 hilconfig(hilp) 1264 register struct hilloop *hilp; 1265 { 1266 u_char db; 1267 int s; 1268 1269 s = splhil(); 1270 #ifdef DEBUG 1271 if (hildebug & HDB_CONFIG) { 1272 printf("hilconfig: reconfigured: "); 1273 send_hil_cmd(hilp->hl_addr, HIL_READLPSTAT, NULL, 0, &db); 1274 printf("LPSTAT %x, ", db); 1275 send_hil_cmd(hilp->hl_addr, HIL_READLPCTRL, NULL, 0, &db); 1276 printf("LPCTRL %x, ", db); 1277 send_hil_cmd(hilp->hl_addr, HIL_READKBDSADR, NULL, 0, &db); 1278 printf("KBDSADR %x\n", db); 1279 hilreport(hilp); 1280 } 1281 #endif 1282 /* 1283 * Determine how many devices are on the loop. 1284 * Mark those as alive and real, all others as dead. 1285 */ 1286 db = 0; 1287 send_hil_cmd(hilp->hl_addr, HIL_READLPSTAT, NULL, 0, &db); 1288 hilp->hl_maxdev = db & LPS_DEVMASK; 1289 for (db = 1; db < NHILD; db++) { 1290 if (db <= hilp->hl_maxdev) 1291 hilp->hl_device[db].hd_flags |= HIL_ALIVE; 1292 else 1293 hilp->hl_device[db].hd_flags &= ~HIL_ALIVE; 1294 hilp->hl_device[db].hd_flags &= ~HIL_PSEUDO; 1295 } 1296 #ifdef DEBUG 1297 if (hildebug & (HDB_CONFIG|HDB_KEYBOARD)) 1298 printf("hilconfig: max device %d\n", hilp->hl_maxdev); 1299 #endif 1300 if (hilp->hl_maxdev == 0) { 1301 hilp->hl_kbddev = 0; 1302 splx(s); 1303 return; 1304 } 1305 /* 1306 * Find out where the keyboards are and record the ITE keyboard 1307 * (first one found). If no keyboards found, we are all done. 1308 */ 1309 db = 0; 1310 send_hil_cmd(hilp->hl_addr, HIL_READKBDSADR, NULL, 0, &db); 1311 #ifdef DEBUG 1312 if (hildebug & HDB_KEYBOARD) 1313 printf("hilconfig: keyboard: KBDSADR %x, old %d, new %d\n", 1314 db, hilp->hl_kbddev, ffs((int)db)); 1315 #endif 1316 hilp->hl_kbddev = ffs((int)db); 1317 if (hilp->hl_kbddev == 0) { 1318 splx(s); 1319 return; 1320 } 1321 /* 1322 * Determine if the keyboard should be cooked or raw and configure it. 1323 */ 1324 db = (hilp->hl_kbdflags & KBD_RAW) ? 0 : 1 << (hilp->hl_kbddev - 1); 1325 send_hil_cmd(hilp->hl_addr, HIL_WRITEKBDSADR, &db, 1, NULL); 1326 /* 1327 * Re-enable autorepeat in raw mode, cooked mode AR is not affected. 1328 */ 1329 if (hilp->hl_kbdflags & (KBD_AR1|KBD_AR2)) { 1330 db = (hilp->hl_kbdflags & KBD_AR1) ? HILAR1 : HILAR2; 1331 hilp->hl_cmddev = hilp->hl_kbddev; 1332 send_hildev_cmd(hilp, hilp->hl_kbddev, db); 1333 hilp->hl_cmddev = 0; 1334 } 1335 /* 1336 * Determine the keyboard language configuration, but don't 1337 * override a user-specified setting. 1338 */ 1339 db = 0; 1340 send_hil_cmd(hilp->hl_addr, HIL_READKBDLANG, NULL, 0, &db); 1341 #ifdef DEBUG 1342 if (hildebug & HDB_KEYBOARD) 1343 printf("hilconfig: language: old %x new %x\n", 1344 hilp->hl_kbdlang, db); 1345 #endif 1346 if (hilp->hl_kbdlang != KBD_SPECIAL) { 1347 struct kbdmap *km; 1348 1349 for (km = kbd_map; km->kbd_code; km++) 1350 if (km->kbd_code == db) { 1351 hilp->hl_kbdlang = db; 1352 /* XXX */ 1353 kbd_keymap = km->kbd_keymap; 1354 kbd_shiftmap = km->kbd_shiftmap; 1355 kbd_ctrlmap = km->kbd_ctrlmap; 1356 kbd_ctrlshiftmap = km->kbd_ctrlshiftmap; 1357 kbd_stringmap = km->kbd_stringmap; 1358 } 1359 } 1360 splx(s); 1361 } 1362 1363 hilreset(hilp) 1364 struct hilloop *hilp; 1365 { 1366 register struct hil_dev *hildevice = hilp->hl_addr; 1367 u_char db; 1368 1369 /* 1370 * Initialize the loop: reconfigure, don't report errors, 1371 * cook keyboards, and enable autopolling. 1372 */ 1373 db = LPC_RECONF | LPC_KBDCOOK | LPC_NOERROR | LPC_AUTOPOLL; 1374 send_hil_cmd(hildevice, HIL_WRITELPCTRL, &db, 1, NULL); 1375 /* 1376 * Delay one second for reconfiguration and then read the the 1377 * data register to clear the interrupt (if the loop reconfigured). 1378 */ 1379 DELAY(1000000); 1380 if (hildevice->hil_stat & HIL_DATA_RDY) 1381 db = hildevice->hil_data; 1382 /* 1383 * The HIL loop may have reconfigured. If so we proceed on, 1384 * if not we loop until a successful reconfiguration is reported 1385 * back to us. The HIL loop will continue to attempt forever. 1386 * Probably not very smart. 1387 */ 1388 do { 1389 send_hil_cmd(hildevice, HIL_READLPSTAT, NULL, 0, &db); 1390 } while ((db & (LPS_CONFFAIL|LPS_CONFGOOD)) == 0); 1391 /* 1392 * At this point, the loop should have reconfigured. 1393 * The reconfiguration interrupt has already called hilconfig() 1394 * so the keyboard has been determined. 1395 */ 1396 send_hil_cmd(hildevice, HIL_INTON, NULL, 0, NULL); 1397 } 1398 1399 hilbeep(hilp, bp) 1400 struct hilloop *hilp; 1401 register struct _hilbell *bp; 1402 { 1403 u_char buf[2]; 1404 1405 buf[0] = ~((bp->duration - 10) / 10); 1406 buf[1] = bp->frequency; 1407 send_hil_cmd(hilp->hl_addr, HIL_SETTONE, buf, 2, NULL); 1408 } 1409 1410 /* 1411 * Locate and return the address of the first ID module, 0 if none present. 1412 */ 1413 hiliddev(hilp) 1414 register struct hilloop *hilp; 1415 { 1416 register int i, len; 1417 1418 #ifdef DEBUG 1419 if (hildebug & HDB_IDMODULE) 1420 printf("hiliddev(%x): looking for idmodule...", hilp); 1421 #endif 1422 for (i = 1; i <= hilp->hl_maxdev; i++) { 1423 hilp->hl_cmdbp = hilp->hl_cmdbuf; 1424 hilp->hl_cmddev = i; 1425 send_hildev_cmd(hilp, i, HILIDENTIFY); 1426 /* 1427 * XXX: the final condition checks to ensure that the 1428 * device ID byte is in the range of the ID module (0x30-0x3F) 1429 */ 1430 len = hilp->hl_cmdbp - hilp->hl_cmdbuf; 1431 if (len > 1 && (hilp->hl_cmdbuf[1] & HILSCBIT) && 1432 (hilp->hl_cmdbuf[0] & 0xF0) == 0x30) { 1433 hilp->hl_cmdbp = hilp->hl_cmdbuf; 1434 hilp->hl_cmddev = i; 1435 send_hildev_cmd(hilp, i, HILSECURITY); 1436 break; 1437 } 1438 } 1439 hilp->hl_cmdbp = hilp->hl_cmdbuf; 1440 hilp->hl_cmddev = 0; 1441 #ifdef DEBUG 1442 if (hildebug & HDB_IDMODULE) 1443 if (i <= hilp->hl_maxdev) 1444 printf("found at %d\n", i); 1445 else 1446 printf("not found\n"); 1447 #endif 1448 return(i <= hilp->hl_maxdev ? i : 0); 1449 } 1450 1451 /* 1452 * Low level routines which actually talk to the 8042 chip. 1453 */ 1454 1455 /* 1456 * Send a command to the 8042 with zero or more bytes of data. 1457 * If rdata is non-null, wait for and return a byte of data. 1458 * We run at splimp() to make the transaction as atomic as 1459 * possible without blocking the clock (is this necessary?) 1460 */ 1461 send_hil_cmd(hildevice, cmd, data, dlen, rdata) 1462 register struct hil_dev *hildevice; 1463 u_char cmd, *data, dlen; 1464 u_char *rdata; 1465 { 1466 u_char status; 1467 int s = splimp(); 1468 1469 HILWAIT(hildevice); 1470 hildevice->hil_cmd = cmd; 1471 while (dlen--) { 1472 HILWAIT(hildevice); 1473 hildevice->hil_data = *data++; 1474 } 1475 if (rdata) { 1476 do { 1477 HILDATAWAIT(hildevice); 1478 status = hildevice->hil_stat; 1479 *rdata = hildevice->hil_data; 1480 } while (((status >> HIL_SSHIFT) & HIL_SMASK) != HIL_68K); 1481 } 1482 splx(s); 1483 } 1484 1485 /* 1486 * Send a command to a device on the loop. 1487 * Since only one command can be active on the loop at any time, 1488 * we must ensure that we are not interrupted during this process. 1489 * Hence we mask interrupts to prevent potential access from most 1490 * interrupt routines and turn off auto-polling to disable the 1491 * internally generated poll commands. 1492 * 1493 * splhigh is extremely conservative but insures atomic operation, 1494 * splimp (clock only interrupts) seems to be good enough in practice. 1495 */ 1496 send_hildev_cmd(hilp, device, cmd) 1497 register struct hilloop *hilp; 1498 char device, cmd; 1499 { 1500 register struct hil_dev *hildevice = hilp->hl_addr; 1501 u_char status, c; 1502 int s = splimp(); 1503 1504 polloff(hildevice); 1505 1506 /* 1507 * Transfer the command and device info to the chip 1508 */ 1509 HILWAIT(hildevice); 1510 hildevice->hil_cmd = HIL_STARTCMD; 1511 HILWAIT(hildevice); 1512 hildevice->hil_data = 8 + device; 1513 HILWAIT(hildevice); 1514 hildevice->hil_data = cmd; 1515 HILWAIT(hildevice); 1516 hildevice->hil_data = HIL_TIMEOUT; 1517 /* 1518 * Trigger the command and wait for completion 1519 */ 1520 HILWAIT(hildevice); 1521 hildevice->hil_cmd = HIL_TRIGGER; 1522 hilp->hl_cmddone = FALSE; 1523 do { 1524 HILDATAWAIT(hildevice); 1525 status = hildevice->hil_stat; 1526 c = hildevice->hil_data; 1527 hil_process_int(status, c); 1528 } while (!hilp->hl_cmddone); 1529 1530 pollon(hildevice); 1531 splx(s); 1532 } 1533 1534 /* 1535 * Turn auto-polling off and on. 1536 * Also disables and enable auto-repeat. Why? 1537 */ 1538 polloff(hildevice) 1539 register struct hil_dev *hildevice; 1540 { 1541 register char db; 1542 1543 /* 1544 * Turn off auto repeat 1545 */ 1546 HILWAIT(hildevice); 1547 hildevice->hil_cmd = HIL_SETARR; 1548 HILWAIT(hildevice); 1549 hildevice->hil_data = 0; 1550 /* 1551 * Turn off auto-polling 1552 */ 1553 HILWAIT(hildevice); 1554 hildevice->hil_cmd = HIL_READLPCTRL; 1555 HILDATAWAIT(hildevice); 1556 db = hildevice->hil_data; 1557 db &= ~LPC_AUTOPOLL; 1558 HILWAIT(hildevice); 1559 hildevice->hil_cmd = HIL_WRITELPCTRL; 1560 HILWAIT(hildevice); 1561 hildevice->hil_data = db; 1562 /* 1563 * Must wait til polling is really stopped 1564 */ 1565 do { 1566 HILWAIT(hildevice); 1567 hildevice->hil_cmd = HIL_READBUSY; 1568 HILDATAWAIT(hildevice); 1569 db = hildevice->hil_data; 1570 } while (db & BSY_LOOPBUSY); 1571 } 1572 1573 pollon(hildevice) 1574 register struct hil_dev *hildevice; 1575 { 1576 register char db; 1577 1578 /* 1579 * Turn on auto polling 1580 */ 1581 HILWAIT(hildevice); 1582 hildevice->hil_cmd = HIL_READLPCTRL; 1583 HILDATAWAIT(hildevice); 1584 db = hildevice->hil_data; 1585 db |= LPC_AUTOPOLL; 1586 HILWAIT(hildevice); 1587 hildevice->hil_cmd = HIL_WRITELPCTRL; 1588 HILWAIT(hildevice); 1589 hildevice->hil_data = db; 1590 /* 1591 * Turn on auto repeat 1592 */ 1593 HILWAIT(hildevice); 1594 hildevice->hil_cmd = HIL_SETARR; 1595 HILWAIT(hildevice); 1596 hildevice->hil_data = ar_format(KBD_ARR); 1597 } 1598 1599 #ifdef DEBUG 1600 printhilpollbuf(hilp) 1601 register struct hilloop *hilp; 1602 { 1603 register u_char *cp; 1604 register int i, len; 1605 1606 cp = hilp->hl_pollbuf; 1607 len = hilp->hl_pollbp - cp; 1608 for (i = 0; i < len; i++) 1609 printf("%x ", hilp->hl_pollbuf[i]); 1610 printf("\n"); 1611 } 1612 1613 printhilcmdbuf(hilp) 1614 register struct hilloop *hilp; 1615 { 1616 register u_char *cp; 1617 register int i, len; 1618 1619 cp = hilp->hl_cmdbuf; 1620 len = hilp->hl_cmdbp - cp; 1621 for (i = 0; i < len; i++) 1622 printf("%x ", hilp->hl_cmdbuf[i]); 1623 printf("\n"); 1624 } 1625 1626 hilreport(hilp) 1627 register struct hilloop *hilp; 1628 { 1629 register int i, len; 1630 int s = splhil(); 1631 1632 for (i = 1; i <= hilp->hl_maxdev; i++) { 1633 hilp->hl_cmdbp = hilp->hl_cmdbuf; 1634 hilp->hl_cmddev = i; 1635 send_hildev_cmd(hilp, i, HILIDENTIFY); 1636 printf("hil%d: id: ", i); 1637 printhilcmdbuf(hilp); 1638 len = hilp->hl_cmdbp - hilp->hl_cmdbuf; 1639 if (len > 1 && (hilp->hl_cmdbuf[1] & HILSCBIT)) { 1640 hilp->hl_cmdbp = hilp->hl_cmdbuf; 1641 hilp->hl_cmddev = i; 1642 send_hildev_cmd(hilp, i, HILSECURITY); 1643 printf("hil%d: sc: ", i); 1644 printhilcmdbuf(hilp); 1645 } 1646 } 1647 hilp->hl_cmdbp = hilp->hl_cmdbuf; 1648 hilp->hl_cmddev = 0; 1649 splx(s); 1650 } 1651 #endif 1652