1/* $OpenBSD: hil.c,v 1.29 2022/01/09 05:42:37 jsg 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/ioctl.h> 72#include <sys/kernel.h> 73#include <sys/proc.h> 74#include <sys/kthread.h> 75 76#include <machine/autoconf.h> 77#include <machine/bus.h> 78#include <machine/cpu.h> 79 80#include <dev/hil/hilreg.h> 81#include <dev/hil/hilvar.h> 82#include <dev/hil/hildevs.h> 83#include <dev/hil/hildevs_data.h> 84 85#include "hilkbd.h" 86 87/* 88 * splhigh is extremely conservative but insures atomic operation, 89 * splvm (clock only interrupts) seems to be good enough in practice. 90 */ 91#define splhil splvm 92 93struct cfdriver hil_cd = { 94 NULL, "hil", DV_DULL 95}; 96 97void hilconfig(struct hil_softc *, u_int); 98void hilempty(struct hil_softc *); 99int hilsubmatch(struct device *, void *, void *); 100void hil_process_int(struct hil_softc *, u_int8_t, u_int8_t); 101int hil_process_poll(struct hil_softc *, u_int8_t, u_int8_t); 102void hil_thread(void *); 103int send_device_cmd(struct hil_softc *sc, u_int device, u_int cmd); 104void polloff(struct hil_softc *); 105void pollon(struct hil_softc *); 106 107static int hilwait(struct hil_softc *); 108static int hildatawait(struct hil_softc *); 109 110#define hil_process_pending(sc) wakeup(&(sc)->sc_pending) 111 112static __inline int 113hilwait(struct hil_softc *sc) 114{ 115 int cnt; 116 117 for (cnt = 50000; cnt != 0; cnt--) { 118 DELAY(1); 119 if ((bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT) & 120 HIL_BUSY) == 0) 121 break; 122 } 123 124 return (cnt); 125} 126 127static __inline int 128hildatawait(struct hil_softc *sc) 129{ 130 int cnt; 131 132 for (cnt = 50000; cnt != 0; cnt--) { 133 DELAY(1); 134 if ((bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT) & 135 HIL_DATA_RDY) != 0) 136 break; 137 } 138 139 return (cnt); 140} 141 142/* 143 * Common HIL bus attachment 144 */ 145 146void 147hil_attach(struct hil_softc *sc, int *hil_is_console) 148{ 149 printf("\n"); 150 151 /* 152 * Initialize loop information 153 */ 154 sc->sc_cmdending = 0; 155 sc->sc_actdev = sc->sc_cmddev = 0; 156 sc->sc_cmddone = 0; 157 sc->sc_cmdbp = sc->sc_cmdbuf; 158 sc->sc_pollbp = sc->sc_pollbuf; 159 sc->sc_console = hil_is_console; 160} 161 162/* 163 * HIL subdevice attachment 164 */ 165 166int 167hildevprint(void *aux, const char *pnp) 168{ 169 struct hil_attach_args *ha = aux; 170 171 if (pnp != NULL) { 172 printf("\"%s\" at %s id %x", 173 ha->ha_descr, pnp, ha->ha_id); 174 } 175 printf(" code %d", ha->ha_code); 176 if (pnp == NULL) { 177 printf(": %s", ha->ha_descr); 178 } 179 180 return (UNCONF); 181} 182 183int 184hilsubmatch(struct device *parent, void *vcf, void *aux) 185{ 186 struct hil_attach_args *ha = aux; 187 struct cfdata *cf = vcf; 188 189 if (cf->cf_loc[0] != -1 && 190 cf->cf_loc[0] != ha->ha_code) 191 return (0); 192 193 return ((*cf->cf_attach->ca_match)(parent, vcf, aux)); 194} 195 196void 197hil_attach_deferred(void *v) 198{ 199 struct hil_softc *sc = v; 200 int tries; 201 u_int8_t db; 202 203 sc->sc_status = HIL_STATUS_BUSY; 204 205 /* 206 * Initialize the loop: reconfigure, don't report errors, 207 * put keyboard in cooked mode, and enable autopolling. 208 */ 209 db = LPC_RECONF | LPC_KBDCOOK | LPC_NOERROR | LPC_AUTOPOLL; 210 send_hil_cmd(sc, HIL_WRITELPCTRL, &db, 1, NULL); 211 212 /* 213 * Delay one second for reconfiguration and then read the 214 * data to clear the interrupt (if the loop reconfigured). 215 */ 216 DELAY(1000000); 217 if (bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT) & 218 HIL_DATA_RDY) { 219 db = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 220 DELAY(1); 221 } 222 223 /* 224 * The HIL loop may have reconfigured. If so we proceed on, 225 * if not we loop a few times until a successful reconfiguration 226 * is reported back to us. If the HIL loop is still lost after a 227 * few seconds, give up. 228 */ 229 for (tries = 10; tries != 0; tries--) { 230 if (send_hil_cmd(sc, HIL_READLPSTAT, NULL, 0, &db) == 0) { 231 if (db & (LPS_CONFFAIL | LPS_CONFGOOD)) 232 break; 233 } 234 235#ifdef HILDEBUG 236 printf("%s: loop not ready, retrying...\n", 237 sc->sc_dev.dv_xname); 238#endif 239 240 DELAY(1000000); 241 } 242 243 if (tries == 0 || (db & LPS_CONFFAIL)) { 244 printf("%s: no devices\n", sc->sc_dev.dv_xname); 245 sc->sc_pending = 0; 246 if (tries == 0) 247 return; 248 } 249 250 /* 251 * Create asynchronous loop event handler thread. 252 */ 253 if (kthread_create(hil_thread, sc, &sc->sc_thread, 254 sc->sc_dev.dv_xname) != 0) { 255 printf("%s: unable to create event thread\n", 256 sc->sc_dev.dv_xname); 257 return; 258 } 259 260 /* 261 * Enable loop interrupts. 262 */ 263 send_hil_cmd(sc, HIL_INTON, NULL, 0, NULL); 264 265 /* 266 * Reconfigure if necessary 267 */ 268 sc->sc_status = HIL_STATUS_READY; 269 hil_process_pending(sc); 270} 271 272/* 273 * Asynchronous event processing 274 */ 275 276int 277hil_intr(void *v) 278{ 279 struct hil_softc *sc = v; 280 u_int8_t c, stat; 281 282 if (cold) 283 return (0); 284 285 stat = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT); 286 287 /* 288 * This should never happen if the interrupt comes from the 289 * loop. 290 */ 291 if ((stat & HIL_DATA_RDY) == 0) 292 return (0); /* not for us */ 293 294 c = bus_space_read_1(sc->sc_bst, sc->sc_bsh, 295 HILP_DATA); /* clears interrupt */ 296 DELAY(1); 297 298 hil_process_int(sc, stat, c); 299 300 if (sc->sc_status != HIL_STATUS_BUSY) 301 hil_process_pending(sc); 302 303 return (1); 304} 305 306void 307hil_process_int(struct hil_softc *sc, u_int8_t stat, u_int8_t c) 308{ 309 struct hildev_softc *dev; 310 311 switch ((stat >> HIL_SSHIFT) & HIL_SMASK) { 312 case HIL_STATUS: 313 if (c & HIL_ERROR) { 314 sc->sc_cmddone = 1; 315 switch (c) { 316 case HIL_RECONFIG: 317 sc->sc_pending = HIL_PENDING_RECONFIG; 318 break; 319 case HIL_UNPLUGGED: 320 sc->sc_pending = HIL_PENDING_UNPLUGGED; 321 break; 322 } 323 break; 324 } 325 if (c & HIL_COMMAND) { 326 if (c & HIL_POLLDATA) { /* End of data */ 327 dev = sc->sc_devices[sc->sc_actdev]; 328 if (dev != NULL && dev->sc_fn != NULL) 329 dev->sc_fn(dev, 330 sc->sc_pollbp - sc->sc_pollbuf, 331 sc->sc_pollbuf); 332 } else { /* End of command */ 333 sc->sc_cmdending = 1; 334 } 335 sc->sc_actdev = 0; 336 } else { 337 if (c & HIL_POLLDATA) { /* Start of polled data */ 338 sc->sc_actdev = (c & HIL_DEVMASK); 339 sc->sc_pollbp = sc->sc_pollbuf; 340 } else { /* Start of command */ 341 if (sc->sc_cmddev == (c & HIL_DEVMASK)) { 342 sc->sc_cmdbp = sc->sc_cmdbuf; 343 sc->sc_actdev = 0; 344 } 345 } 346 } 347 break; 348 case HIL_DATA: 349 if (sc->sc_actdev != 0) /* Collecting poll data */ 350 *sc->sc_pollbp++ = c; 351 else { 352 if (sc->sc_cmddev != 0) { /* Collecting cmd data */ 353 if (sc->sc_cmdending) { 354 sc->sc_cmddone = 1; 355 sc->sc_cmdending = 0; 356 } else 357 *sc->sc_cmdbp++ = c; 358 } 359 } 360 break; 361 } 362} 363 364/* 365 * Same as above, but in polled mode: return data as it gets seen, instead 366 * of buffering it. 367 */ 368int 369hil_process_poll(struct hil_softc *sc, u_int8_t stat, u_int8_t c) 370{ 371 u_int8_t db; 372 373 switch ((stat >> HIL_SSHIFT) & HIL_SMASK) { 374 case HIL_STATUS: 375 if (c & HIL_ERROR) { 376 sc->sc_cmddone = 1; 377 switch (c) { 378 case HIL_RECONFIG: 379 /* 380 * Remember that a configuration event 381 * occurred; it will be processed upon 382 * leaving polled mode... 383 */ 384 sc->sc_pending = HIL_PENDING_RECONFIG; 385 /* 386 * However, the keyboard will come back as 387 * cooked, and we rely on it being in raw 388 * mode. So, put it back in raw mode right 389 * now. 390 */ 391 db = 0; 392 send_hil_cmd(sc, HIL_WRITEKBDSADR, &db, 393 1, NULL); 394 break; 395 case HIL_UNPLUGGED: 396 /* 397 * Remember that an unplugged event 398 * occurred; it will be processed upon 399 * leaving polled mode... 400 */ 401 sc->sc_pending = HIL_PENDING_UNPLUGGED; 402 break; 403 } 404 break; 405 } 406 if (c & HIL_COMMAND) { 407 if (!(c & HIL_POLLDATA)) { 408 /* End of command */ 409 sc->sc_cmdending = 1; 410 } 411 sc->sc_actdev = 0; 412 } else { 413 if (c & HIL_POLLDATA) { 414 /* Start of polled data */ 415 sc->sc_actdev = (c & HIL_DEVMASK); 416 sc->sc_pollbp = sc->sc_pollbuf; 417 } else { 418 /* Start of command - should not happen */ 419 if (sc->sc_cmddev == (c & HIL_DEVMASK)) { 420 sc->sc_cmdbp = sc->sc_cmdbuf; 421 sc->sc_actdev = 0; 422 } 423 } 424 } 425 break; 426 case HIL_DATA: 427 if (sc->sc_actdev != 0) /* Collecting poll data */ 428 return 1; 429 else { 430 if (sc->sc_cmddev != 0) { /* Discarding cmd data */ 431 if (sc->sc_cmdending) { 432 sc->sc_cmddone = 1; 433 sc->sc_cmdending = 0; 434 } 435 } 436 } 437 break; 438 } 439 440 return 0; 441} 442 443void 444hil_thread(void *arg) 445{ 446 struct hil_softc *sc = arg; 447 int s; 448 449 for (;;) { 450 s = splhil(); 451 if (sc->sc_pending == 0) { 452 splx(s); 453 tsleep_nsec(&sc->sc_pending, PWAIT, "hil_event", 454 INFSLP); 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 */ 488void 489hilconfig(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 */ 583void 584hilempty(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 splx(s); 620 return; 621 } 622 } 623 624 /* 625 * Now detach all hil devices. 626 */ 627 for (id = sc->sc_maxdev + 1; id < NHILD; id++) { 628 if (sc->sc_devices[id] != NULL) 629 config_detach((struct device *)sc->sc_devices[id], 630 DETACH_FORCE); 631 sc->sc_devices[id] = NULL; 632 } 633 634 sc->sc_cmdbp = sc->sc_cmdbuf; 635 636 splx(s); 637} 638 639/* 640 * Low level routines which actually talk to the 8042 chip. 641 */ 642 643/* 644 * Send a command to the 8042 with zero or more bytes of data. 645 * If rdata is non-null, wait for and return a byte of data. 646 */ 647int 648send_hil_cmd(struct hil_softc *sc, u_int cmd, u_int8_t *data, u_int dlen, 649 u_int8_t *rdata) 650{ 651 u_int8_t status; 652 int s; 653 654 s = splhil(); 655 656 if (hilwait(sc) == 0) { 657#ifdef HILDEBUG 658 printf("%s: no answer from the loop\n", sc->sc_dev.dv_xname); 659#endif 660 splx(s); 661 return (EBUSY); 662 } 663 664 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, cmd); 665 while (dlen--) { 666 hilwait(sc); 667 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, *data++); 668 DELAY(1); 669 } 670 if (rdata) { 671 do { 672 if (hildatawait(sc) == 0) { 673#ifdef HILDEBUG 674 printf("%s: no answer from the loop\n", 675 sc->sc_dev.dv_xname); 676#endif 677 break; 678 } 679 status = bus_space_read_1(sc->sc_bst, sc->sc_bsh, 680 HILP_STAT); 681 *rdata = bus_space_read_1(sc->sc_bst, sc->sc_bsh, 682 HILP_DATA); 683 DELAY(1); 684 } while (((status >> HIL_SSHIFT) & HIL_SMASK) != HIL_68K); 685 } 686 splx(s); 687 return (0); 688} 689 690/* 691 * Send a command to a device on the loop. 692 * Since only one command can be active on the loop at any time, 693 * we must ensure that we are not interrupted during this process. 694 * Hence we mask interrupts to prevent potential access from most 695 * interrupt routines and turn off auto-polling to disable the 696 * internally generated poll commands. 697 * Needs to be called at splhil(). 698 */ 699int 700send_device_cmd(struct hil_softc *sc, u_int device, u_int cmd) 701{ 702 u_int8_t status, c; 703 int rc = 0; 704 705 polloff(sc); 706 707 sc->sc_cmdbp = sc->sc_cmdbuf; 708 sc->sc_cmddev = device; 709 710 if (hilwait(sc) == 0) { 711#ifdef HILDEBUG 712 printf("%s: no answer from device %d\n", 713 sc->sc_dev.dv_xname, device); 714#endif 715 rc = EBUSY; 716 goto out; 717 } 718 719 /* 720 * Transfer the command and device info to the chip 721 */ 722 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_STARTCMD); 723 hilwait(sc); 724 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, 8 + device); 725 hilwait(sc); 726 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, cmd); 727 hilwait(sc); 728 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, HIL_TIMEOUT); 729 730 /* 731 * Trigger the command and wait for completion 732 */ 733 hilwait(sc); 734 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_TRIGGER); 735 sc->sc_cmddone = 0; 736 do { 737 if (hildatawait(sc) == 0) { 738#ifdef HILDEBUG 739 printf("%s: no answer from device %d\n", 740 sc->sc_dev.dv_xname, device); 741#endif 742 rc = EBUSY; 743 break; 744 } 745 status = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT); 746 c = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 747 DELAY(1); 748 hil_process_int(sc, status, c); 749 } while (sc->sc_cmddone == 0); 750out: 751 sc->sc_cmddev = 0; 752 753 pollon(sc); 754 return (rc); 755} 756 757int 758send_hildev_cmd(struct hildev_softc *dev, u_int cmd, 759 u_int8_t *outbuf, u_int *outlen) 760{ 761 struct hil_softc *sc = (struct hil_softc *)dev->sc_dev.dv_parent; 762 int s, rc; 763 764 s = splhil(); 765 766 if ((rc = send_device_cmd(sc, dev->sc_code, cmd)) == 0) { 767 /* 768 * Return the command response in the buffer if necessary 769 */ 770 if (outbuf != NULL && outlen != NULL) { 771 *outlen = min(*outlen, sc->sc_cmdbp - sc->sc_cmdbuf); 772 bcopy(sc->sc_cmdbuf, outbuf, *outlen); 773 } 774 } 775 776 splx(s); 777 return (rc); 778} 779 780/* 781 * Turn auto-polling off and on. 782 */ 783void 784polloff(struct hil_softc *sc) 785{ 786 u_int8_t db; 787 788 if (hilwait(sc) == 0) 789 return; 790 791 /* 792 * Turn off auto repeat 793 */ 794 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_SETARR); 795 hilwait(sc); 796 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, 0); 797 798 /* 799 * Turn off auto-polling 800 */ 801 hilwait(sc); 802 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_READLPCTRL); 803 hildatawait(sc); 804 db = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 805 db &= ~LPC_AUTOPOLL; 806 hilwait(sc); 807 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_WRITELPCTRL); 808 hilwait(sc); 809 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, db); 810 811 /* 812 * Must wait until polling is really stopped 813 */ 814 do { 815 hilwait(sc); 816 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_READBUSY); 817 hildatawait(sc); 818 db = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 819 } while (db & BSY_LOOPBUSY); 820 821 sc->sc_cmddone = 0; 822 sc->sc_cmddev = 0; 823} 824 825void 826pollon(struct hil_softc *sc) 827{ 828 u_int8_t db; 829 830 if (hilwait(sc) == 0) 831 return; 832 833 /* 834 * Turn on auto polling 835 */ 836 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_READLPCTRL); 837 hildatawait(sc); 838 db = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 839 db |= LPC_AUTOPOLL; 840 hilwait(sc); 841 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_WRITELPCTRL); 842 hilwait(sc); 843 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, db); 844 845 /* 846 * Turn off auto repeat - we emulate this through wscons 847 */ 848 hilwait(sc); 849 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_SETARR); 850 hilwait(sc); 851 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, 0); 852 DELAY(1); 853} 854 855void 856hil_set_poll(struct hil_softc *sc, int on) 857{ 858 if (on) { 859 pollon(sc); 860 } else { 861 hil_process_pending(sc); 862 send_hil_cmd(sc, HIL_INTON, NULL, 0, NULL); 863 } 864} 865 866int 867hil_poll_data(struct hildev_softc *dev, u_int8_t *stat, u_int8_t *data) 868{ 869 struct hil_softc *sc = (struct hil_softc *)dev->sc_dev.dv_parent; 870 u_int8_t s, c; 871 872 s = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT); 873 if ((s & HIL_DATA_RDY) == 0) 874 return -1; 875 876 c = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 877 DELAY(1); 878 879 if (hil_process_poll(sc, s, c)) { 880 /* Discard any data not for us */ 881 if (sc->sc_actdev == dev->sc_code) { 882 *stat = s; 883 *data = c; 884 return 0; 885 } 886 } 887 888 return -1; 889} 890