]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/s390/kvm/kvm_virtio.c
virtio: Add transport feature handling stub for virtio_ring.
[linux-2.6-omap-h63xx.git] / drivers / s390 / kvm / kvm_virtio.c
index 5ab34340919be3a417caf1ad5bfd50ff91f1054d..79954bd6bfa5a02b963e6c2868c9c5ad22bed5af 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/err.h>
 #include <linux/virtio.h>
 #include <linux/virtio_config.h>
+#include <linux/virtio_console.h>
 #include <linux/interrupt.h>
 #include <linux/virtio_ring.h>
 #include <linux/pfn.h>
@@ -87,16 +88,20 @@ static u32 kvm_get_features(struct virtio_device *vdev)
        return features;
 }
 
-static void kvm_set_features(struct virtio_device *vdev, u32 features)
+static void kvm_finalize_features(struct virtio_device *vdev)
 {
-       unsigned int i;
+       unsigned int i, bits;
        struct kvm_device_desc *desc = to_kvmdev(vdev)->desc;
        /* Second half of bitmap is features we accept. */
        u8 *out_features = kvm_vq_features(desc) + desc->feature_len;
 
+       /* Give virtio_ring a chance to accept features. */
+       vring_transport_features(vdev);
+
        memset(out_features, 0, desc->feature_len);
-       for (i = 0; i < min(desc->feature_len * 8, 32); i++) {
-               if (features & (1 << i))
+       bits = min_t(unsigned, desc->feature_len, sizeof(vdev->features)) * 8;
+       for (i = 0; i < bits; i++) {
+               if (test_bit(i, vdev->features))
                        out_features[i / 8] |= (1 << (i % 8));
        }
 }
@@ -222,7 +227,7 @@ static void kvm_del_vq(struct virtqueue *vq)
  */
 static struct virtio_config_ops kvm_vq_configspace_ops = {
        .get_features = kvm_get_features,
-       .set_features = kvm_set_features,
+       .finalize_features = kvm_finalize_features,
        .get = kvm_get,
        .set = kvm_set,
        .get_status = kvm_get_status,
@@ -333,6 +338,25 @@ static int __init kvm_devices_init(void)
        return 0;
 }
 
+/* code for early console output with virtio_console */
+static __init int early_put_chars(u32 vtermno, const char *buf, int count)
+{
+       char scratch[17];
+       unsigned int len = count;
+
+       if (len > sizeof(scratch) - 1)
+               len = sizeof(scratch) - 1;
+       scratch[len] = '\0';
+       memcpy(scratch, buf, len);
+       kvm_hypercall1(KVM_S390_VIRTIO_NOTIFY, __pa(scratch));
+       return len;
+}
+
+void s390_virtio_console_init(void)
+{
+       virtio_cons_early_init(early_put_chars);
+}
+
 /*
  * We do this after core stuff, but before the drivers.
  */