1 /* $OpenBSD: hil.c,v 1.26 2015/05/15 13:32:08 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/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 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 */ 647 int 648 send_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 */ 699 int 700 send_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); 750 out: 751 sc->sc_cmddev = 0; 752 753 pollon(sc); 754 return (rc); 755 } 756 757 int 758 send_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 */ 783 void 784 polloff(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 825 void 826 pollon(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 855 void 856 hil_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 866 int 867 hil_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