1 /* $OpenBSD: hil.c,v 1.23 2006/12/16 20:07:13 miod 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 "%s", 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 } 469 } 470 471 /* 472 * Called after the loop has reconfigured. Here we need to: 473 * - determine how many devices are on the loop 474 * (some may have been added or removed) 475 * - make sure all keyboards are in raw mode 476 * 477 * Note that our device state is now potentially invalid as 478 * devices may no longer be where they were. What we should 479 * do here is either track where the devices went and move 480 * state around accordingly... 481 * 482 * Note that it is necessary that we operate the loop with the keyboards 483 * in raw mode: they won't cause the loop to generate an NMI if the 484 * ``reset'' key combination is pressed, and we do not handle the hil 485 * NMI interrupt... 486 */ 487 void 488 hilconfig(struct hil_softc *sc, u_int knowndevs) 489 { 490 struct hil_attach_args ha; 491 u_int8_t db; 492 int id, s; 493 494 s = splhil(); 495 496 /* 497 * Determine how many devices are on the loop. 498 */ 499 db = 0; 500 send_hil_cmd(sc, HIL_READLPSTAT, NULL, 0, &db); 501 sc->sc_maxdev = db & LPS_DEVMASK; 502 #ifdef HILDEBUG 503 printf("%s: %d device(s)\n", sc->sc_dev.dv_xname, sc->sc_maxdev); 504 #endif 505 506 /* 507 * Put all keyboards in raw mode now. 508 */ 509 db = 0; 510 send_hil_cmd(sc, HIL_WRITEKBDSADR, &db, 1, NULL); 511 512 /* 513 * If the loop grew, attach new devices. 514 */ 515 for (id = knowndevs + 1; id <= sc->sc_maxdev; id++) { 516 int len; 517 const struct hildevice *hd; 518 519 if (send_device_cmd(sc, id, HIL_IDENTIFY) != 0) { 520 printf("%s: no answer from device %d\n", 521 sc->sc_dev.dv_xname, id); 522 continue; 523 } 524 525 len = sc->sc_cmdbp - sc->sc_cmdbuf; 526 if (len == 0) { 527 #ifdef HILDEBUG 528 printf("%s: no device at code %d\n", 529 sc->sc_dev.dv_xname, id); 530 #endif 531 continue; 532 } 533 534 /* Identify and attach device */ 535 for (hd = hildevs; hd->minid >= 0; hd++) 536 if (sc->sc_cmdbuf[0] >= hd->minid && 537 sc->sc_cmdbuf[0] <= hd->maxid) { 538 539 ha.ha_console = *sc->sc_console; 540 ha.ha_code = id; 541 ha.ha_type = hd->type; 542 ha.ha_descr = hd->descr; 543 ha.ha_infolen = len; 544 bcopy(sc->sc_cmdbuf, ha.ha_info, len); 545 546 sc->sc_devices[id] = (struct hildev_softc *) 547 config_found_sm(&sc->sc_dev, &ha, hildevprint, 548 hilsubmatch); 549 550 #if NHILKBD > 0 551 /* 552 * If we just attached a keyboard as console, 553 * console choice is not indeterminate anymore. 554 */ 555 if (sc->sc_devices[id] != NULL && 556 ha.ha_type == HIL_DEVICE_KEYBOARD && 557 ha.ha_console != 0) 558 *sc->sc_console = 1; 559 #endif 560 } 561 } 562 563 /* 564 * Detach remaining devices, if the loop has shrunk. 565 */ 566 for (id = sc->sc_maxdev + 1; id < NHILD; id++) { 567 if (sc->sc_devices[id] != NULL) 568 config_detach((struct device *)sc->sc_devices[id], 569 DETACH_FORCE); 570 sc->sc_devices[id] = NULL; 571 } 572 573 sc->sc_cmdbp = sc->sc_cmdbuf; 574 575 splx(s); 576 } 577 578 /* 579 * Called after the loop has been unplugged. We simply force detach of 580 * all our children. 581 */ 582 void 583 hilempty(struct hil_softc *sc) 584 { 585 u_int8_t db; 586 int id, s; 587 u_int oldmaxdev; 588 589 s = splhil(); 590 591 /* 592 * Wait for the loop to be stable. 593 */ 594 for (;;) { 595 if (send_hil_cmd(sc, HIL_READLPSTAT, NULL, 0, &db) == 0) { 596 if (db & (LPS_CONFFAIL | LPS_CONFGOOD)) 597 break; 598 } else { 599 db = LPS_CONFFAIL; 600 break; 601 } 602 } 603 604 if (db & LPS_CONFFAIL) { 605 sc->sc_maxdev = 0; 606 } else { 607 db = 0; 608 send_hil_cmd(sc, HIL_READLPSTAT, NULL, 0, &db); 609 oldmaxdev = sc->sc_maxdev; 610 sc->sc_maxdev = db & LPS_DEVMASK; 611 612 if (sc->sc_maxdev != 0) { 613 /* 614 * The loop was not unplugged after all, but its 615 * configuration has changed. 616 */ 617 hilconfig(sc, oldmaxdev); 618 return; 619 } 620 } 621 622 /* 623 * Now detach all hil devices. 624 */ 625 for (id = sc->sc_maxdev + 1; id < NHILD; id++) { 626 if (sc->sc_devices[id] != NULL) 627 config_detach((struct device *)sc->sc_devices[id], 628 DETACH_FORCE); 629 sc->sc_devices[id] = NULL; 630 } 631 632 sc->sc_cmdbp = sc->sc_cmdbuf; 633 634 splx(s); 635 } 636 637 /* 638 * Low level routines which actually talk to the 8042 chip. 639 */ 640 641 /* 642 * Send a command to the 8042 with zero or more bytes of data. 643 * If rdata is non-null, wait for and return a byte of data. 644 */ 645 int 646 send_hil_cmd(struct hil_softc *sc, u_int cmd, u_int8_t *data, u_int dlen, 647 u_int8_t *rdata) 648 { 649 u_int8_t status; 650 int s; 651 652 s = splhil(); 653 654 if (hilwait(sc) == 0) { 655 #ifdef HILDEBUG 656 printf("%s: no answer from the loop\n", sc->sc_dev.dv_xname); 657 #endif 658 splx(s); 659 return (EBUSY); 660 } 661 662 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, cmd); 663 while (dlen--) { 664 hilwait(sc); 665 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, *data++); 666 DELAY(1); 667 } 668 if (rdata) { 669 do { 670 if (hildatawait(sc) == 0) { 671 #ifdef HILDEBUG 672 printf("%s: no answer from the loop\n", 673 sc->sc_dev.dv_xname); 674 #endif 675 break; 676 } 677 status = bus_space_read_1(sc->sc_bst, sc->sc_bsh, 678 HILP_STAT); 679 *rdata = bus_space_read_1(sc->sc_bst, sc->sc_bsh, 680 HILP_DATA); 681 DELAY(1); 682 } while (((status >> HIL_SSHIFT) & HIL_SMASK) != HIL_68K); 683 } 684 splx(s); 685 return (0); 686 } 687 688 /* 689 * Send a command to a device on the loop. 690 * Since only one command can be active on the loop at any time, 691 * we must ensure that we are not interrupted during this process. 692 * Hence we mask interrupts to prevent potential access from most 693 * interrupt routines and turn off auto-polling to disable the 694 * internally generated poll commands. 695 * Needs to be called at splhil(). 696 */ 697 int 698 send_device_cmd(struct hil_softc *sc, u_int device, u_int cmd) 699 { 700 u_int8_t status, c; 701 int rc = 0; 702 703 polloff(sc); 704 705 sc->sc_cmdbp = sc->sc_cmdbuf; 706 sc->sc_cmddev = device; 707 708 if (hilwait(sc) == 0) { 709 #ifdef HILDEBUG 710 printf("%s: no answer from device %d\n", 711 sc->sc_dev.dv_xname, device); 712 #endif 713 rc = EBUSY; 714 goto out; 715 } 716 717 /* 718 * Transfer the command and device info to the chip 719 */ 720 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_STARTCMD); 721 hilwait(sc); 722 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, 8 + device); 723 hilwait(sc); 724 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, cmd); 725 hilwait(sc); 726 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, HIL_TIMEOUT); 727 728 /* 729 * Trigger the command and wait for completion 730 */ 731 hilwait(sc); 732 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_TRIGGER); 733 sc->sc_cmddone = 0; 734 do { 735 if (hildatawait(sc) == 0) { 736 #ifdef HILDEBUG 737 printf("%s: no answer from device %d\n", 738 sc->sc_dev.dv_xname, device); 739 #endif 740 rc = EBUSY; 741 break; 742 } 743 status = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT); 744 c = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 745 DELAY(1); 746 hil_process_int(sc, status, c); 747 } while (sc->sc_cmddone == 0); 748 out: 749 sc->sc_cmddev = 0; 750 751 pollon(sc); 752 return (rc); 753 } 754 755 int 756 send_hildev_cmd(struct hildev_softc *dev, u_int cmd, 757 u_int8_t *outbuf, u_int *outlen) 758 { 759 struct hil_softc *sc = (struct hil_softc *)dev->sc_dev.dv_parent; 760 int s, rc; 761 762 s = splhil(); 763 764 if ((rc = send_device_cmd(sc, dev->sc_code, cmd)) == 0) { 765 /* 766 * Return the command response in the buffer if necessary 767 */ 768 if (outbuf != NULL && outlen != NULL) { 769 *outlen = min(*outlen, sc->sc_cmdbp - sc->sc_cmdbuf); 770 bcopy(sc->sc_cmdbuf, outbuf, *outlen); 771 } 772 } 773 774 splx(s); 775 return (rc); 776 } 777 778 /* 779 * Turn auto-polling off and on. 780 */ 781 void 782 polloff(struct hil_softc *sc) 783 { 784 u_int8_t db; 785 786 if (hilwait(sc) == 0) 787 return; 788 789 /* 790 * Turn off auto repeat 791 */ 792 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_SETARR); 793 hilwait(sc); 794 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, 0); 795 796 /* 797 * Turn off auto-polling 798 */ 799 hilwait(sc); 800 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_READLPCTRL); 801 hildatawait(sc); 802 db = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 803 db &= ~LPC_AUTOPOLL; 804 hilwait(sc); 805 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_WRITELPCTRL); 806 hilwait(sc); 807 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, db); 808 809 /* 810 * Must wait until polling is really stopped 811 */ 812 do { 813 hilwait(sc); 814 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_READBUSY); 815 hildatawait(sc); 816 db = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 817 } while (db & BSY_LOOPBUSY); 818 819 sc->sc_cmddone = 0; 820 sc->sc_cmddev = 0; 821 } 822 823 void 824 pollon(struct hil_softc *sc) 825 { 826 u_int8_t db; 827 828 if (hilwait(sc) == 0) 829 return; 830 831 /* 832 * Turn on auto polling 833 */ 834 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_READLPCTRL); 835 hildatawait(sc); 836 db = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 837 db |= LPC_AUTOPOLL; 838 hilwait(sc); 839 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_WRITELPCTRL); 840 hilwait(sc); 841 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, db); 842 843 /* 844 * Turn off auto repeat - we emulate this through wscons 845 */ 846 hilwait(sc); 847 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_SETARR); 848 hilwait(sc); 849 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, 0); 850 DELAY(1); 851 } 852 853 void 854 hil_set_poll(struct hil_softc *sc, int on) 855 { 856 if (on) { 857 pollon(sc); 858 } else { 859 hil_process_pending(sc); 860 send_hil_cmd(sc, HIL_INTON, NULL, 0, NULL); 861 } 862 } 863 864 int 865 hil_poll_data(struct hildev_softc *dev, u_int8_t *stat, u_int8_t *data) 866 { 867 struct hil_softc *sc = (struct hil_softc *)dev->sc_dev.dv_parent; 868 u_int8_t s, c; 869 870 s = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT); 871 if ((s & HIL_DATA_RDY) == 0) 872 return -1; 873 874 c = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA); 875 DELAY(1); 876 877 if (hil_process_poll(sc, s, c)) { 878 /* Discard any data not for us */ 879 if (sc->sc_actdev == dev->sc_code) { 880 *stat = s; 881 *data = c; 882 return 0; 883 } 884 } 885 886 return -1; 887 } 888