diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-05-12 10:10:03 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-05-12 10:10:03 +0100 |
commit | de239d043fbfddbcb509e64186f963697127983e (patch) | |
tree | 572eae02c73c3850771a8895cc5712d14bccc8f0 /extras/mini-os/fbfront.c | |
parent | aa7e17e11bb354d0cda598c7e6ccff29b210eb1c (diff) | |
download | xen-de239d043fbfddbcb509e64186f963697127983e.tar.gz xen-de239d043fbfddbcb509e64186f963697127983e.tar.bz2 xen-de239d043fbfddbcb509e64186f963697127983e.zip |
pvfb/ioemu: transmit refresh interval advice from backend to frontend
which permits the frontend to avoid useless polls.
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Diffstat (limited to 'extras/mini-os/fbfront.c')
-rw-r--r-- | extras/mini-os/fbfront.c | 55 |
1 files changed, 55 insertions, 0 deletions
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 + |