Home | History | Annotate | Line # | Download | only in hil
      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