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