From de239d043fbfddbcb509e64186f963697127983e Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 12 May 2008 10:10:03 +0100 Subject: pvfb/ioemu: transmit refresh interval advice from backend to frontend which permits the frontend to avoid useless polls. Signed-off-by: Samuel Thibault --- extras/mini-os/fbfront.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'extras/mini-os/fbfront.c') diff --git a/extras/mini-os/fbfront.c b/extras/mini-os/fbfront.c index 3a361b829c..d5acadf085 100644 --- a/extras/mini-os/fbfront.c +++ b/extras/mini-os/fbfront.c @@ -255,13 +255,57 @@ struct fbfront_dev { int offset; xenbus_event_queue events; + +#ifdef HAVE_LIBC + int fd; +#endif }; void fbfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data) { +#ifdef HAVE_LIBC + struct fbfront_dev *dev = data; + int fd = dev->fd; + + files[fd].read = 1; +#endif wake_up(&fbfront_queue); } +int fbfront_receive(struct fbfront_dev *dev, union xenfb_in_event *buf, int n) +{ + struct xenfb_page *page = dev->page; + uint32_t prod, cons; + int i; + +#ifdef HAVE_LIBC + files[dev->fd].read = 0; + mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */ +#endif + + prod = page->in_prod; + + if (prod == page->in_cons) + return 0; + + rmb(); /* ensure we see ring contents up to prod */ + + for (i = 0, cons = page->in_cons; i < n && cons != prod; i++, cons++) + memcpy(buf + i, &XENFB_IN_RING_REF(page, cons), sizeof(*buf)); + + mb(); /* ensure we got ring contents */ + page->in_cons = cons; + notify_remote_via_evtchn(dev->evtchn); + +#ifdef HAVE_LIBC + if (cons != prod) + /* still some events to read */ + files[dev->fd].read = 1; +#endif + + return i; +} + struct fbfront_dev *init_fbfront(char *nodename, unsigned long *mfns, int width, int height, int depth, int stride, int n) { xenbus_transaction_t xbt; @@ -482,3 +526,14 @@ void shutdown_fbfront(struct fbfront_dev *dev) free(dev->backend); free(dev); } + +#ifdef HAVE_LIBC +int fbfront_open(struct fbfront_dev *dev) +{ + dev->fd = alloc_fd(FTYPE_FB); + printk("fb_open(%s) -> %d\n", dev->nodename, dev->fd); + files[dev->fd].fb.dev = dev; + return dev->fd; +} +#endif + -- cgit v1.2.3