xfs: remove done roadmap item from xfs-delayed-logging-design.txt
[safe/jmp/linux-2.6] / Documentation / lguest / lguest.c
index 950cde6..3119f5d 100644 (file)
@@ -34,7 +34,6 @@
 #include <sys/uio.h>
 #include <termios.h>
 #include <getopt.h>
-#include <zlib.h>
 #include <assert.h>
 #include <sched.h>
 #include <limits.h>
@@ -133,6 +132,9 @@ struct device {
        /* Is it operational */
        bool running;
 
+       /* Does Guest want an intrrupt on empty? */
+       bool irq_on_empty;
+
        /* Device-specific data. */
        void *priv;
 };
@@ -301,7 +303,7 @@ static void *map_zeroed_pages(unsigned int num)
        addr = mmap(NULL, getpagesize() * num,
                    PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0);
        if (addr == MAP_FAILED)
-               err(1, "Mmaping %u pages of /dev/zero", num);
+               err(1, "Mmapping %u pages of /dev/zero", num);
 
        /*
         * One neat mmap feature is that you can close the fd, and it
@@ -623,10 +625,13 @@ static void trigger_irq(struct virtqueue *vq)
                return;
        vq->pending_used = 0;
 
-       /* If they don't want an interrupt, don't send one, unless empty. */
-       if ((vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)
-           && lg_last_avail(vq) != vq->vring.avail->idx)
-               return;
+       /* If they don't want an interrupt, don't send one... */
+       if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) {
+               /* ... unless they've asked us to force one on empty. */
+               if (!vq->dev->irq_on_empty
+                   || lg_last_avail(vq) != vq->vring.avail->idx)
+                       return;
+       }
 
        /* Send the Guest an interrupt tell them we used something up. */
        if (write(lguest_fd, buf, sizeof(buf)) != 0)
@@ -1042,6 +1047,15 @@ static void create_thread(struct virtqueue *vq)
        close(vq->eventfd);
 }
 
+static bool accepted_feature(struct device *dev, unsigned int bit)
+{
+       const u8 *features = get_feature_bits(dev) + dev->feature_len;
+
+       if (dev->feature_len < bit / CHAR_BIT)
+               return false;
+       return features[bit / CHAR_BIT] & (1 << (bit % CHAR_BIT));
+}
+
 static void start_device(struct device *dev)
 {
        unsigned int i;
@@ -1055,6 +1069,8 @@ static void start_device(struct device *dev)
                verbose(" %02x", get_feature_bits(dev)
                        [dev->feature_len+i]);
 
+       dev->irq_on_empty = accepted_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY);
+
        for (vq = dev->vq; vq; vq = vq->next) {
                if (vq->service)
                        create_thread(vq);