1 /* $OpenBSD: hil.c,v 1.25 2013/11/18 20:21:51 deraadt Exp $ */ 2 /* 3 * Copyright (c) 2003, 2004, Miodrag Vallat. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 * 27 */ 28 29 /* 30 * Copyright (c) 1988 University of Utah. 31 * Copyright (c) 1990, 1993 32 * The Regents of the University of California. All rights reserved. 33 * 34 * This code is derived from software contributed to Berkeley by 35 * the Systems Programming Group of the University of Utah Computer 36 * Science Department. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. Neither the name of the University nor the names of its contributors 47 * may be used to endorse or promote products derived from this software 48 * without specific prior written permission. 49 * 50 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60 * SUCH DAMAGE. 61 * 62 * from: Utah $Hdr: hil.c 1.38 92/01/21$ 63 * 64 * @(#)hil.c 8.2 (Berkeley) 1/12/94 65 */ 66 67 #include <sys/param.h> 68 #include <sys/systm.h> 69 #include <sys/conf.h> 70 #include <sys/device.h> 71 #include <sys/file.h> 72 #include <sys/ioctl.h> 73 #include <sys/kernel.h> 74 #include <sys/proc.h> 75 #include <sys/kthread.h> 76 77 #include <machine/autoconf.h> 78 #include <machine/bus.h> 79 #include <machine/cpu.h> 80 81 #include <dev/hil/hilreg.h> 82 #include <dev/hil/hilvar.h> 83 #include <dev/hil/hildevs.h> 84 #include <dev/hil/hildevs_data.h> 85 86 #include "hilkbd.h" 87 88 /* 89 * splhigh is extremely conservative but insures atomic operation, 90 * splvm (clock only interrupts) seems to be good enough in practice. 91 */ 92 #define splhil splvm 93 94 struct cfdriver hil_cd = { 95 NULL, "hil", DV_DULL 96 }; 97 98 void hilconfig(struct hil_softc *, u_int); 99 void hilempty(struct hil_softc *); 100 int hilsubmatch(struct device *, void *, void *); 101 void hil_process_int(struct hil_softc *, u_int8_t, u_int8_t); 102 int hil_process_poll(struct hil_softc *, u_int8_t, u_int8_t); 103 void hil_thread(void *); 104 int send_device_cmd(struct hil_softc *sc, u_int device, u_int cmd); 105 void polloff(struct hil_softc *); 106 void pollon(struct hil_softc *); 107 108 static int hilwait(struct hil_softc *); 109 static int hildatawait(struct hil_softc *); 110 111 #define hil_process_pending(sc) wakeup(&(sc)->sc_pending) 112 113 static __inline int 114 hilwait(struct hil_softc *sc) 115 { 116 int cnt; 117 118 for (cnt = 50000; cnt != 0; cnt--) { 119 DELAY(1); 120 if ((bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT) & 121 HIL_BUSY) == 0) 122 break; 123 } 124 125 return (cnt); 126 } 127 128 static __inline int 129 hildatawait(struct hil_softc *sc) 130 { 131 int cnt; 132 133 for (cnt = 50000; cnt != 0; cnt--) { 134 DELAY(1); 135 if ((bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT) & 136 HIL_DATA_RDY) != 0) 137 break; 138 } 139 140 return (cnt); 141 } 142 143 /* 144 * Common HIL bus attachment 145 */ 146 147 void 148 hil_attach(struct hil_softc *sc, int *hil_is_console) 149 { 150 printf("\n"); 151 152 /* 153 * Initialize loop information 154 */ 155 sc->sc_cmdending = 0; 156 sc->sc_actdev = sc->sc_cmddev = 0; 157 sc->sc_cmddone = 0; 158 sc->sc_cmdbp = sc->sc_cmdbuf; 159 sc->sc_pollbp = sc->sc_pollbuf; 160 sc->sc_console = hil_is_console; 161 } 162 163 /* 164 * HIL subdevice attachment 165 */ 166 167 int 168 hildevprint(void *aux, const char *pnp) 169 { 170 struct hil_attach_args *ha = aux; 171 172 if (pnp != NULL) { 173 printf("\"%s\" at %s id %x", 174 ha->ha_descr, pnp, ha->ha_id); 175 } 176 printf(" code %d", ha->ha_code); 177 if (pnp == NULL) { 178 printf(": %s", ha->ha_descr); 179 } 180 181 return (UNCONF); 182 } 183 184 int 185 hilsubmatch(struct device *parent, void *vcf, void *aux) 186 { 187 struct hil_attach_args *ha = aux; 188 struct cfdata *cf = vcf; 189 190 if (cf->cf_loc[0] != -1 && 191 cf->cf_loc[0] != ha->ha_code) 192 return (0); 193 194 return ((*cf->cf_attach->ca_match)(parent, vcf, aux)); 195 } 196 197 void 198 hil_attach_deferred(void *v) 199 { 200 struct hil_softc *sc = v; 201 int tries; 202 u_int8_t db; 203 204 sc->sc_status = HIL_STATUS_BUSY; 205 206 /* 207 * Initialize the loop: reconfigure, don't report errors, 208 * put keyboard in cooked mode, and enable autopolling. 209 */ 210 db = LPC_RECONF | LPC_KBDCOOK | LPC_NOERROR | LPC_AUTOPOLL; 211 send_hil_cmd(sc, HIL_WRITELPCTRL, &db, 1, NULL); 212 213 /* 214 * Delay one second for reconfiguration and then read the 215 * data to clear the interrupt (if the loop reconfigured). 216 */ 217 DELAY(1000000); 218 if (bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT) & 219 HIL_DATA_RDY) { 220 db = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 221 DELAY(1); 222 } 223 224 /* 225 * The HIL loop may have reconfigured. If so we proceed on, 226 * if not we loop a few times until a successful reconfiguration 227 * is reported back to us. If the HIL loop is still lost after a 228 * few seconds, give up. 229 */ 230 for (tries = 10; tries != 0; tries--) { 231 if (send_hil_cmd(sc, HIL_READLPSTAT, NULL, 0, &db) == 0) { 232 if (db & (LPS_CONFFAIL | LPS_CONFGOOD)) 233 break; 234 } 235 236 #ifdef HILDEBUG 237 printf("%s: loop not ready, retrying...\n", 238 sc->sc_dev.dv_xname); 239 #endif 240 241 DELAY(1000000); 242 } 243 244 if (tries == 0 || (db & LPS_CONFFAIL)) { 245 printf("%s: no devices\n", sc->sc_dev.dv_xname); 246 sc->sc_pending = 0; 247 if (tries == 0) 248 return; 249 } 250 251 /* 252 * Create asynchronous loop event handler thread. 253 */ 254 if (kthread_create(hil_thread, sc, &sc->sc_thread, 255 sc->sc_dev.dv_xname) != 0) { 256 printf("%s: unable to create event thread\n", 257 sc->sc_dev.dv_xname); 258 return; 259 } 260 261 /* 262 * Enable loop interrupts. 263 */ 264 send_hil_cmd(sc, HIL_INTON, NULL, 0, NULL); 265 266 /* 267 * Reconfigure if necessary 268 */ 269 sc->sc_status = HIL_STATUS_READY; 270 hil_process_pending(sc); 271 } 272 273 /* 274 * Asynchronous event processing 275 */ 276 277 int 278 hil_intr(void *v) 279 { 280 struct hil_softc *sc = v; 281 u_int8_t c, stat; 282 283 if (cold) 284 return (0); 285 286 stat = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT); 287 288 /* 289 * This should never happen if the interrupt comes from the 290 * loop. 291 */ 292 if ((stat & HIL_DATA_RDY) == 0) 293 return (0); /* not for us */ 294 295 c = bus_space_read_1(sc->sc_bst, sc->sc_bsh, 296 HILP_DATA); /* clears interrupt */ 297 DELAY(1); 298 299 hil_process_int(sc, stat, c); 300 301 if (sc->sc_status != HIL_STATUS_BUSY) 302 hil_process_pending(sc); 303 304 return (1); 305 } 306 307 void 308 hil_process_int(struct hil_softc *sc, u_int8_t stat, u_int8_t c) 309 { 310 struct hildev_softc *dev; 311 312 switch ((stat >> HIL_SSHIFT) & HIL_SMASK) { 313 case HIL_STATUS: 314 if (c & HIL_ERROR) { 315 sc->sc_cmddone = 1; 316 switch (c) { 317 case HIL_RECONFIG: 318 sc->sc_pending = HIL_PENDING_RECONFIG; 319 break; 320 case HIL_UNPLUGGED: 321 sc->sc_pending = HIL_PENDING_UNPLUGGED; 322 break; 323 } 324 break; 325 } 326 if (c & HIL_COMMAND) { 327 if (c & HIL_POLLDATA) { /* End of data */ 328 dev = sc->sc_devices[sc->sc_actdev]; 329 if (dev != NULL && dev->sc_fn != NULL) 330 dev->sc_fn(dev, 331 sc->sc_pollbp - sc->sc_pollbuf, 332 sc->sc_pollbuf); 333 } else { /* End of command */ 334 sc->sc_cmdending = 1; 335 } 336 sc->sc_actdev = 0; 337 } else { 338 if (c & HIL_POLLDATA) { /* Start of polled data */ 339 sc->sc_actdev = (c & HIL_DEVMASK); 340 sc->sc_pollbp = sc->sc_pollbuf; 341 } else { /* Start of command */ 342 if (sc->sc_cmddev == (c & HIL_DEVMASK)) { 343 sc->sc_cmdbp = sc->sc_cmdbuf; 344 sc->sc_actdev = 0; 345 } 346 } 347 } 348 break; 349 case HIL_DATA: 350 if (sc->sc_actdev != 0) /* Collecting poll data */ 351 *sc->sc_pollbp++ = c; 352 else { 353 if (sc->sc_cmddev != 0) { /* Collecting cmd data */ 354 if (sc->sc_cmdending) { 355 sc->sc_cmddone = 1; 356 sc->sc_cmdending = 0; 357 } else 358 *sc->sc_cmdbp++ = c; 359 } 360 } 361 break; 362 } 363 } 364 365 /* 366 * Same as above, but in polled mode: return data as it gets seen, instead 367 * of buffering it. 368 */ 369 int 370 hil_process_poll(struct hil_softc *sc, u_int8_t stat, u_int8_t c) 371 { 372 u_int8_t db; 373 374 switch ((stat >> HIL_SSHIFT) & HIL_SMASK) { 375 case HIL_STATUS: 376 if (c & HIL_ERROR) { 377 sc->sc_cmddone = 1; 378 switch (c) { 379 case HIL_RECONFIG: 380 /* 381 * Remember that a configuration event 382 * occurred; it will be processed upon 383 * leaving polled mode... 384 */ 385 sc->sc_pending = HIL_PENDING_RECONFIG; 386 /* 387 * However, the keyboard will come back as 388 * cooked, and we rely on it being in raw 389 * mode. So, put it back in raw mode right 390 * now. 391 */ 392 db = 0; 393 send_hil_cmd(sc, HIL_WRITEKBDSADR, &db, 394 1, NULL); 395 break; 396 case HIL_UNPLUGGED: 397 /* 398 * Remember that an unplugged event 399 * occured; it will be processed upon 400 * leaving polled mode... 401 */ 402 sc->sc_pending = HIL_PENDING_UNPLUGGED; 403 break; 404 } 405 break; 406 } 407 if (c & HIL_COMMAND) { 408 if (!(c & HIL_POLLDATA)) { 409 /* End of command */ 410 sc->sc_cmdending = 1; 411 } 412 sc->sc_actdev = 0; 413 } else { 414 if (c & HIL_POLLDATA) { 415 /* Start of polled data */ 416 sc->sc_actdev = (c & HIL_DEVMASK); 417 sc->sc_pollbp = sc->sc_pollbuf; 418 } else { 419 /* Start of command - should not happen */ 420 if (sc->sc_cmddev == (c & HIL_DEVMASK)) { 421 sc->sc_cmdbp = sc->sc_cmdbuf; 422 sc->sc_actdev = 0; 423 } 424 } 425 } 426 break; 427 case HIL_DATA: 428 if (sc->sc_actdev != 0) /* Collecting poll data */ 429 return 1; 430 else { 431 if (sc->sc_cmddev != 0) { /* Discarding cmd data */ 432 if (sc->sc_cmdending) { 433 sc->sc_cmddone = 1; 434 sc->sc_cmdending = 0; 435 } 436 } 437 } 438 break; 439 } 440 441 return 0; 442 } 443 444 void 445 hil_thread(void *arg) 446 { 447 struct hil_softc *sc = arg; 448 int s; 449 450 for (;;) { 451 s = splhil(); 452 if (sc->sc_pending == 0) { 453 splx(s); 454 (void)tsleep(&sc->sc_pending, PWAIT, "hil_event", 0); 455 continue; 456 } 457 458 switch (sc->sc_pending) { 459 case HIL_PENDING_RECONFIG: 460 sc->sc_pending = 0; 461 hilconfig(sc, sc->sc_maxdev); 462 break; 463 case HIL_PENDING_UNPLUGGED: 464 sc->sc_pending = 0; 465 hilempty(sc); 466 break; 467 } 468 splx(s); 469 } 470 } 471 472 /* 473 * Called after the loop has reconfigured. Here we need to: 474 * - determine how many devices are on the loop 475 * (some may have been added or removed) 476 * - make sure all keyboards are in raw mode 477 * 478 * Note that our device state is now potentially invalid as 479 * devices may no longer be where they were. What we should 480 * do here is either track where the devices went and move 481 * state around accordingly... 482 * 483 * Note that it is necessary that we operate the loop with the keyboards 484 * in raw mode: they won't cause the loop to generate an NMI if the 485 * ``reset'' key combination is pressed, and we do not handle the hil 486 * NMI interrupt... 487 */ 488 void 489 hilconfig(struct hil_softc *sc, u_int knowndevs) 490 { 491 struct hil_attach_args ha; 492 u_int8_t db; 493 int id, s; 494 495 s = splhil(); 496 497 /* 498 * Determine how many devices are on the loop. 499 */ 500 db = 0; 501 send_hil_cmd(sc, HIL_READLPSTAT, NULL, 0, &db); 502 sc->sc_maxdev = db & LPS_DEVMASK; 503 #ifdef HILDEBUG 504 printf("%s: %d device(s)\n", sc->sc_dev.dv_xname, sc->sc_maxdev); 505 #endif 506 507 /* 508 * Put all keyboards in raw mode now. 509 */ 510 db = 0; 511 send_hil_cmd(sc, HIL_WRITEKBDSADR, &db, 1, NULL); 512 513 /* 514 * If the loop grew, attach new devices. 515 */ 516 for (id = knowndevs + 1; id <= sc->sc_maxdev; id++) { 517 int len; 518 const struct hildevice *hd; 519 520 if (send_device_cmd(sc, id, HIL_IDENTIFY) != 0) { 521 printf("%s: no answer from device %d\n", 522 sc->sc_dev.dv_xname, id); 523 continue; 524 } 525 526 len = sc->sc_cmdbp - sc->sc_cmdbuf; 527 if (len == 0) { 528 #ifdef HILDEBUG 529 printf("%s: no device at code %d\n", 530 sc->sc_dev.dv_xname, id); 531 #endif 532 continue; 533 } 534 535 /* Identify and attach device */ 536 for (hd = hildevs; hd->minid >= 0; hd++) 537 if (sc->sc_cmdbuf[0] >= hd->minid && 538 sc->sc_cmdbuf[0] <= hd->maxid) { 539 540 ha.ha_console = *sc->sc_console; 541 ha.ha_code = id; 542 ha.ha_type = hd->type; 543 ha.ha_descr = hd->descr; 544 ha.ha_infolen = len; 545 bcopy(sc->sc_cmdbuf, ha.ha_info, len); 546 547 sc->sc_devices[id] = (struct hildev_softc *) 548 config_found_sm(&sc->sc_dev, &ha, hildevprint, 549 hilsubmatch); 550 551 #if NHILKBD > 0 552 /* 553 * If we just attached a keyboard as console, 554 * console choice is not indeterminate anymore. 555 */ 556 if (sc->sc_devices[id] != NULL && 557 ha.ha_type == HIL_DEVICE_KEYBOARD && 558 ha.ha_console != 0) 559 *sc->sc_console = 1; 560 #endif 561 } 562 } 563 564 /* 565 * Detach remaining devices, if the loop has shrunk. 566 */ 567 for (id = sc->sc_maxdev + 1; id < NHILD; id++) { 568 if (sc->sc_devices[id] != NULL) 569 config_detach((struct device *)sc->sc_devices[id], 570 DETACH_FORCE); 571 sc->sc_devices[id] = NULL; 572 } 573 574 sc->sc_cmdbp = sc->sc_cmdbuf; 575 576 splx(s); 577 } 578 579 /* 580 * Called after the loop has been unplugged. We simply force detach of 581 * all our children. 582 */ 583 void 584 hilempty(struct hil_softc *sc) 585 { 586 u_int8_t db; 587 int id, s; 588 u_int oldmaxdev; 589 590 s = splhil(); 591 592 /* 593 * Wait for the loop to be stable. 594 */ 595 for (;;) { 596 if (send_hil_cmd(sc, HIL_READLPSTAT, NULL, 0, &db) == 0) { 597 if (db & (LPS_CONFFAIL | LPS_CONFGOOD)) 598 break; 599 } else { 600 db = LPS_CONFFAIL; 601 break; 602 } 603 } 604 605 if (db & LPS_CONFFAIL) { 606 sc->sc_maxdev = 0; 607 } else { 608 db = 0; 609 send_hil_cmd(sc, HIL_READLPSTAT, NULL, 0, &db); 610 oldmaxdev = sc->sc_maxdev; 611 sc->sc_maxdev = db & LPS_DEVMASK; 612 613 if (sc->sc_maxdev != 0) { 614 /* 615 * The loop was not unplugged after all, but its 616 * configuration has changed. 617 */ 618 hilconfig(sc, oldmaxdev); 619 return; 620 } 621 } 622 623 /* 624 * Now detach all hil devices. 625 */ 626 for (id = sc->sc_maxdev + 1; id < NHILD; id++) { 627 if (sc->sc_devices[id] != NULL) 628 config_detach((struct device *)sc->sc_devices[id], 629 DETACH_FORCE); 630 sc->sc_devices[id] = NULL; 631 } 632 633 sc->sc_cmdbp = sc->sc_cmdbuf; 634 635 splx(s); 636 } 637 638 /* 639 * Low level routines which actually talk to the 8042 chip. 640 */ 641 642 /* 643 * Send a command to the 8042 with zero or more bytes of data. 644 * If rdata is non-null, wait for and return a byte of data. 645 */ 646 int 647 send_hil_cmd(struct hil_softc *sc, u_int cmd, u_int8_t *data, u_int dlen, 648 u_int8_t *rdata) 649 { 650 u_int8_t status; 651 int s; 652 653 s = splhil(); 654 655 if (hilwait(sc) == 0) { 656 #ifdef HILDEBUG 657 printf("%s: no answer from the loop\n", sc->sc_dev.dv_xname); 658 #endif 659 splx(s); 660 return (EBUSY); 661 } 662 663 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, cmd); 664 while (dlen--) { 665 hilwait(sc); 666 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, *data++); 667 DELAY(1); 668 } 669 if (rdata) { 670 do { 671 if (hildatawait(sc) == 0) { 672 #ifdef HILDEBUG 673 printf("%s: no answer from the loop\n", 674 sc->sc_dev.dv_xname); 675 #endif 676 break; 677 } 678 status = bus_space_read_1(sc->sc_bst, sc->sc_bsh, 679 HILP_STAT); 680 *rdata = bus_space_read_1(sc->sc_bst, sc->sc_bsh, 681 HILP_DATA); 682 DELAY(1); 683 } while (((status >> HIL_SSHIFT) & HIL_SMASK) != HIL_68K); 684 } 685 splx(s); 686 return (0); 687 } 688 689 /* 690 * Send a command to a device on the loop. 691 * Since only one command can be active on the loop at any time, 692 * we must ensure that we are not interrupted during this process. 693 * Hence we mask interrupts to prevent potential access from most 694 * interrupt routines and turn off auto-polling to disable the 695 * internally generated poll commands. 696 * Needs to be called at splhil(). 697 */ 698 int 699 send_device_cmd(struct hil_softc *sc, u_int device, u_int cmd) 700 { 701 u_int8_t status, c; 702 int rc = 0; 703 704 polloff(sc); 705 706 sc->sc_cmdbp = sc->sc_cmdbuf; 707 sc->sc_cmddev = device; 708 709 if (hilwait(sc) == 0) { 710 #ifdef HILDEBUG 711 printf("%s: no answer from device %d\n", 712 sc->sc_dev.dv_xname, device); 713 #endif 714 rc = EBUSY; 715 goto out; 716 } 717 718 /* 719 * Transfer the command and device info to the chip 720 */ 721 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_STARTCMD); 722 hilwait(sc); 723 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, 8 + device); 724 hilwait(sc); 725 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, cmd); 726 hilwait(sc); 727 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, HIL_TIMEOUT); 728 729 /* 730 * Trigger the command and wait for completion 731 */ 732 hilwait(sc); 733 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_TRIGGER); 734 sc->sc_cmddone = 0; 735 do { 736 if (hildatawait(sc) == 0) { 737 #ifdef HILDEBUG 738 printf("%s: no answer from device %d\n", 739 sc->sc_dev.dv_xname, device); 740 #endif 741 rc = EBUSY; 742 break; 743 } 744 status = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT); 745 c = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 746 DELAY(1); 747 hil_process_int(sc, status, c); 748 } while (sc->sc_cmddone == 0); 749 out: 750 sc->sc_cmddev = 0; 751 752 pollon(sc); 753 return (rc); 754 } 755 756 int 757 send_hildev_cmd(struct hildev_softc *dev, u_int cmd, 758 u_int8_t *outbuf, u_int *outlen) 759 { 760 struct hil_softc *sc = (struct hil_softc *)dev->sc_dev.dv_parent; 761 int s, rc; 762 763 s = splhil(); 764 765 if ((rc = send_device_cmd(sc, dev->sc_code, cmd)) == 0) { 766 /* 767 * Return the command response in the buffer if necessary 768 */ 769 if (outbuf != NULL && outlen != NULL) { 770 *outlen = min(*outlen, sc->sc_cmdbp - sc->sc_cmdbuf); 771 bcopy(sc->sc_cmdbuf, outbuf, *outlen); 772 } 773 } 774 775 splx(s); 776 return (rc); 777 } 778 779 /* 780 * Turn auto-polling off and on. 781 */ 782 void 783 polloff(struct hil_softc *sc) 784 { 785 u_int8_t db; 786 787 if (hilwait(sc) == 0) 788 return; 789 790 /* 791 * Turn off auto repeat 792 */ 793 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_SETARR); 794 hilwait(sc); 795 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, 0); 796 797 /* 798 * Turn off auto-polling 799 */ 800 hilwait(sc); 801 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_READLPCTRL); 802 hildatawait(sc); 803 db = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 804 db &= ~LPC_AUTOPOLL; 805 hilwait(sc); 806 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_WRITELPCTRL); 807 hilwait(sc); 808 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, db); 809 810 /* 811 * Must wait until polling is really stopped 812 */ 813 do { 814 hilwait(sc); 815 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_READBUSY); 816 hildatawait(sc); 817 db = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 818 } while (db & BSY_LOOPBUSY); 819 820 sc->sc_cmddone = 0; 821 sc->sc_cmddev = 0; 822 } 823 824 void 825 pollon(struct hil_softc *sc) 826 { 827 u_int8_t db; 828 829 if (hilwait(sc) == 0) 830 return; 831 832 /* 833 * Turn on auto polling 834 */ 835 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_READLPCTRL); 836 hildatawait(sc); 837 db = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 838 db |= LPC_AUTOPOLL; 839 hilwait(sc); 840 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_WRITELPCTRL); 841 hilwait(sc); 842 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, db); 843 844 /* 845 * Turn off auto repeat - we emulate this through wscons 846 */ 847 hilwait(sc); 848 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_SETARR); 849 hilwait(sc); 850 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, 0); 851 DELAY(1); 852 } 853 854 void 855 hil_set_poll(struct hil_softc *sc, int on) 856 { 857 if (on) { 858 pollon(sc); 859 } else { 860 hil_process_pending(sc); 861 send_hil_cmd(sc, HIL_INTON, NULL, 0, NULL); 862 } 863 } 864 865 int 866 hil_poll_data(struct hildev_softc *dev, u_int8_t *stat, u_int8_t *data) 867 { 868 struct hil_softc *sc = (struct hil_softc *)dev->sc_dev.dv_parent; 869 u_int8_t s, c; 870 871 s = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT); 872 if ((s & HIL_DATA_RDY) == 0) 873 return -1; 874 875 c = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 876 DELAY(1); 877 878 if (hil_process_poll(sc, s, c)) { 879 /* Discard any data not for us */ 880 if (sc->sc_actdev == dev->sc_code) { 881 *stat = s; 882 *data = c; 883 return 0; 884 } 885 } 886 887 return -1; 888 } 889