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