static uint32_t events_read(void *x, target_phys_addr_t off) { events_state *s = (events_state *) x; int offset = off; // - s->base; /* This gross hack below is used to ensure that we * only raise the IRQ when the kernel driver is * properly ready! If done before this, the driver * becomes confused and ignores all input events * as soon as one was buffered! */ if (offset == REG_LEN && s->page == PAGE_ABSDATA) { if (s->state == STATE_BUFFERED) qemu_irq_raise(s->irq); s->state = STATE_LIVE; } if (offset == REG_READ) return dequeue_event(s); else if (offset == REG_LEN) return get_page_len(s); else if (offset >= REG_DATA) return get_page_data(s, offset - REG_DATA); return 0; // this shouldn't happen, if the driver does the right thing }
static uint32_t events_read(void *x, target_phys_addr_t off) { events_state *s = (events_state *) x; int offset = off; // - s->base; if (offset == REG_READ) return dequeue_event(s); else if (offset == REG_LEN) return get_page_len(s); else if (offset >= REG_DATA) return get_page_data(s, offset - REG_DATA); return 0; // this shouldn't happen, if the driver does the right thing }
static int get_page_data(events_state *s, int offset) { int page_len = get_page_len(s); int page = s->page; if (offset > page_len) return 0; if (page == PAGE_NAME) return s->name[offset]; if (page >= PAGE_EVBITS && page <= PAGE_EVBITS + EV_MAX) return s->ev_bits[page - PAGE_EVBITS].bits[offset]; if (page == PAGE_ABSDATA) return s->abs_info[offset / sizeof(s->abs_info[0])]; return 0; }