示例#1
0
static int
cmx_filter_read(struct knote *kn, long hint)
{
	struct cmx_softc *sc = (struct cmx_softc *)kn->kn_hook;
	int ready = 0;
        uint8_t bsr = 0;

        if (sc == NULL || sc->dying) {
		kn->kn_flags |= EV_EOF;
                return (1);
	}

        bsr = cmx_read_BSR(sc);
	if (cmx_test(bsr, BSR_BULK_IN_FULL, 1)) {
		ready = 1;
	} else {
		CMX_LOCK(sc);
		if (!sc->polling) {
			sc->polling = 1;
			callout_reset(&sc->ch, POLL_TICKS,
				      cmx_tick, sc);
		}
		CMX_UNLOCK(sc);
	}

	return (ready);
}
示例#2
0
/*
 * Interrupt handler.  Currently has no function except to
 * print register status (if debugging is also enabled).
 */
static void
cmx_intr(void *arg)
{
	struct cmx_softc *sc = (struct cmx_softc *)arg;

	if (sc == NULL || sc->dying)
		return;

	DEBUG_printf(sc->dev, "received interrupt (SCR=%b BSR=%b)\n",
			cmx_read_SCR(sc), SCRBITS,
			cmx_read_BSR(sc), BSRBITS);

	return;
}
示例#3
0
/*
 * Periodical callout routine, polling the reader for data
 * availability.  If the reader signals data ready for reading,
 * wakes up the processes which are waiting in select()/poll().
 * Otherwise, reschedules itself with a delay of POLL_TICKS.
 */
static void
cmx_tick(void *xsc)
{
	struct cmx_softc *sc = xsc;
	uint8_t bsr;

	CMX_LOCK(sc);
	if (sc->polling && !sc->dying) {
		bsr = cmx_read_BSR(sc);
		DEBUG_printf(sc->dev, "BSR=%b\n", bsr, BSRBITS);
		if (cmx_test(bsr, BSR_BULK_IN_FULL, 1)) {
			sc->polling = 0;
			selwakeuppri(&sc->sel, PZERO);
		} else {
			callout_reset(&sc->ch, POLL_TICKS, cmx_tick, sc);
		}
	}
	CMX_UNLOCK(sc);
}
示例#4
0
/*
 * Poll handler.  Writing is always possible, reading is only possible
 * if BSR_BULK_IN_FULL is set.  Will start the cmx_tick callout and
 * set sc->polling.
 */
static int
cmx_poll(struct cdev *cdev, int events, struct thread *td)
{
	struct cmx_softc *sc = cdev->si_drv1;
	int revents = 0;
	uint8_t bsr = 0;

	if (sc == NULL || sc->dying)
		return ENXIO;

	bsr = cmx_read_BSR(sc);
	DEBUG_printf(sc->dev, "called (events=%b BSR=%b)\n",
			events, POLLBITS, bsr, BSRBITS);

	revents = events & (POLLOUT | POLLWRNORM);
	if (events & (POLLIN | POLLRDNORM)) {
		if (cmx_test(bsr, BSR_BULK_IN_FULL, 1)) {
			revents |= events & (POLLIN | POLLRDNORM);
		} else {
			selrecord(td, &sc->sel);
			CMX_LOCK(sc);
			if (!sc->polling) {
				DEBUG_printf(sc->dev, "enabling polling\n");
				sc->polling = 1;
				callout_reset(&sc->ch, POLL_TICKS,
						cmx_tick, sc);
			} else {
				DEBUG_printf(sc->dev, "already polling\n");
			}
			CMX_UNLOCK(sc);
		}
	}

	DEBUG_printf(sc->dev, "success (revents=%b)\n", revents, POLLBITS);

	return revents;
}