diff options
Diffstat (limited to 'Documentation/lguest/lguest.c')
-rw-r--r-- | Documentation/lguest/lguest.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index 84bbb190bf7b..ba9373f82ab5 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
@@ -134,6 +134,9 @@ struct device { | |||
134 | /* Is it operational */ | 134 | /* Is it operational */ |
135 | bool running; | 135 | bool running; |
136 | 136 | ||
137 | /* Does Guest want an intrrupt on empty? */ | ||
138 | bool irq_on_empty; | ||
139 | |||
137 | /* Device-specific data. */ | 140 | /* Device-specific data. */ |
138 | void *priv; | 141 | void *priv; |
139 | }; | 142 | }; |
@@ -624,10 +627,13 @@ static void trigger_irq(struct virtqueue *vq) | |||
624 | return; | 627 | return; |
625 | vq->pending_used = 0; | 628 | vq->pending_used = 0; |
626 | 629 | ||
627 | /* If they don't want an interrupt, don't send one, unless empty. */ | 630 | /* If they don't want an interrupt, don't send one... */ |
628 | if ((vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) | 631 | if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) { |
629 | && lg_last_avail(vq) != vq->vring.avail->idx) | 632 | /* ... unless they've asked us to force one on empty. */ |
630 | return; | 633 | if (!vq->dev->irq_on_empty |
634 | || lg_last_avail(vq) != vq->vring.avail->idx) | ||
635 | return; | ||
636 | } | ||
631 | 637 | ||
632 | /* Send the Guest an interrupt tell them we used something up. */ | 638 | /* Send the Guest an interrupt tell them we used something up. */ |
633 | if (write(lguest_fd, buf, sizeof(buf)) != 0) | 639 | if (write(lguest_fd, buf, sizeof(buf)) != 0) |
@@ -1043,6 +1049,15 @@ static void create_thread(struct virtqueue *vq) | |||
1043 | close(vq->eventfd); | 1049 | close(vq->eventfd); |
1044 | } | 1050 | } |
1045 | 1051 | ||
1052 | static bool accepted_feature(struct device *dev, unsigned int bit) | ||
1053 | { | ||
1054 | const u8 *features = get_feature_bits(dev) + dev->feature_len; | ||
1055 | |||
1056 | if (dev->feature_len < bit / CHAR_BIT) | ||
1057 | return false; | ||
1058 | return features[bit / CHAR_BIT] & (1 << (bit % CHAR_BIT)); | ||
1059 | } | ||
1060 | |||
1046 | static void start_device(struct device *dev) | 1061 | static void start_device(struct device *dev) |
1047 | { | 1062 | { |
1048 | unsigned int i; | 1063 | unsigned int i; |
@@ -1056,6 +1071,8 @@ static void start_device(struct device *dev) | |||
1056 | verbose(" %02x", get_feature_bits(dev) | 1071 | verbose(" %02x", get_feature_bits(dev) |
1057 | [dev->feature_len+i]); | 1072 | [dev->feature_len+i]); |
1058 | 1073 | ||
1074 | dev->irq_on_empty = accepted_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY); | ||
1075 | |||
1059 | for (vq = dev->vq; vq; vq = vq->next) { | 1076 | for (vq = dev->vq; vq; vq = vq->next) { |
1060 | if (vq->service) | 1077 | if (vq->service) |
1061 | create_thread(vq); | 1078 | create_thread(vq); |