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