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