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