int pckbcintr_hard(void *vsc) { struct pckbc_softc *sc = (struct pckbc_softc *)vsc; struct pckbc_internal *t = sc->id; u_char stat; pckbc_slot_t slot; struct pckbc_slotdata *q; int served = 0, data, next, s; for(;;) { stat = bus_space_read_1(t->t_iot, t->t_ioh_c, 0); if (!(stat & KBS_DIB)) break; served = 1; slot = (t->t_haveaux && (stat & 0x20)) ? PCKBC_AUX_SLOT : PCKBC_KBD_SLOT; q = t->t_slotdata[slot]; if (!q) { /* XXX do something for live insertion? */ printf("pckbc: no dev for slot %d\n", slot); KBD_DELAY; (void) bus_space_read_1(t->t_iot, t->t_ioh_d, 0); continue; } KBD_DELAY; data = bus_space_read_1(t->t_iot, t->t_ioh_d, 0); rnd_add_uint32(&q->rnd_source, (stat<<8)|data); if (q->polling) { q->poll_data = data; q->poll_stat = stat; break; /* pckbc_poll_data() will get it */ } #if 0 /* XXXBJH */ if (CMD_IN_QUEUE(q) && pckbc_cmdresponse(t, slot, data)) continue; #endif s = splhigh(); next = (t->rbuf_write+1) % PCKBC_RBUF_SIZE; if (next == t->rbuf_read) { splx(s); break; } t->rbuf[t->rbuf_write].data = data; t->rbuf[t->rbuf_write].slot = slot; t->rbuf_write = next; splx(s); } return (served); }
int pckbcintr_internal(struct pckbc_internal *t, struct pckbc_softc *sc) { u_char stat; pckbc_slot_t slot; struct pckbc_slotdata *q; int served = 0, data; /* reschedule timeout further into the idle times */ if (timeout_pending(&t->t_poll)) timeout_add_sec(&t->t_poll, 1); for(;;) { stat = bus_space_read_1(t->t_iot, t->t_ioh_c, 0); if (!(stat & KBS_DIB)) break; served = 1; slot = (t->t_haveaux && (stat & KBS_AUXDATA)) ? PCKBC_AUX_SLOT : PCKBC_KBD_SLOT; q = t->t_slotdata[slot]; if (!q) { /* XXX do something for live insertion? */ #ifdef PCKBCDEBUG printf("pckbcintr: no dev for slot %d\n", slot); #endif KBD_DELAY; (void) bus_space_read_1(t->t_iot, t->t_ioh_d, 0); continue; } if (q->polling) break; /* pckbc_poll_data() will get it */ KBD_DELAY; data = bus_space_read_1(t->t_iot, t->t_ioh_d, 0); if (CMD_IN_QUEUE(q) && pckbc_cmdresponse(t, slot, data)) continue; if (sc != NULL) { if (sc->inputhandler[slot]) (*sc->inputhandler[slot])(sc->inputarg[slot], data); #ifdef PCKBCDEBUG else printf("pckbcintr: slot %d lost %d\n", slot, data); #endif } } return (served); }
int pckbc_poll_data(pckbc_tag_t self, pckbc_slot_t slot) { struct pckbc_internal *t = self; struct pckbc_slotdata *q = t->t_slotdata[slot]; int c; c = pckbc_poll_data1(t->t_iot, t->t_ioh_d, t->t_ioh_c, slot, t->t_haveaux); if (c != -1 && q && CMD_IN_QUEUE(q)) { /* we jumped into a running command - try to deliver the response */ if (pckbc_cmdresponse(t, slot, c)) return (-1); } return (c); }