virtio_balloon: fix towards_target when deflating balloon
[safe/jmp/linux-2.6] / drivers / virtio / virtio_pci.c
index 26f787d..c7dc37c 100644 (file)
@@ -37,7 +37,7 @@ struct virtio_pci_device
        struct pci_dev *pci_dev;
 
        /* the IO mapping for the PCI config space */
-       void *ioaddr;
+       void __iomem *ioaddr;
 
        /* a list of queues so we can dispatch IRQs */
        spinlock_t lock;
@@ -78,32 +78,33 @@ static struct device virtio_pci_root = {
        .bus_id         = "virtio-pci",
 };
 
-/* Unique numbering for devices under the kvm root */
-static unsigned int dev_index;
-
 /* Convert a generic virtio device to our structure */
 static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev)
 {
        return container_of(vdev, struct virtio_pci_device, vdev);
 }
 
-/* virtio config->feature() implementation */
-static bool vp_feature(struct virtio_device *vdev, unsigned bit)
+/* virtio config->get_features() implementation */
+static u32 vp_get_features(struct virtio_device *vdev)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
-       u32 mask;
-
-       /* Since this function is supposed to have the side effect of
-        * enabling a queried feature, we simulate that by doing a read
-        * from the host feature bitmask and then writing to the guest
-        * feature bitmask */
-       mask = ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES);
-       if (mask & (1 << bit)) {
-               mask |= (1 << bit);
-               iowrite32(mask, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES);
-       }
 
-       return !!(mask & (1 << bit));
+       /* When someone needs more than 32 feature bits, we'll need to
+        * steal a bit to indicate that the rest are somewhere else. */
+       return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES);
+}
+
+/* virtio config->finalize_features() implementation */
+static void vp_finalize_features(struct virtio_device *vdev)
+{
+       struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+
+       /* Give virtio_ring a chance to accept features. */
+       vring_transport_features(vdev);
+
+       /* We only support 32 feature bits. */
+       BUILD_BUG_ON(ARRAY_SIZE(vdev->features) != 1);
+       iowrite32(vdev->features[0], vp_dev->ioaddr+VIRTIO_PCI_GUEST_FEATURES);
 }
 
 /* virtio config->get() implementation */
@@ -111,7 +112,7 @@ static void vp_get(struct virtio_device *vdev, unsigned offset,
                   void *buf, unsigned len)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
-       void *ioaddr = vp_dev->ioaddr + VIRTIO_PCI_CONFIG + offset;
+       void __iomem *ioaddr = vp_dev->ioaddr + VIRTIO_PCI_CONFIG + offset;
        u8 *ptr = buf;
        int i;
 
@@ -125,7 +126,7 @@ static void vp_set(struct virtio_device *vdev, unsigned offset,
                   const void *buf, unsigned len)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
-       void *ioaddr = vp_dev->ioaddr + VIRTIO_PCI_CONFIG + offset;
+       void __iomem *ioaddr = vp_dev->ioaddr + VIRTIO_PCI_CONFIG + offset;
        const u8 *ptr = buf;
        int i;
 
@@ -145,14 +146,14 @@ static void vp_set_status(struct virtio_device *vdev, u8 status)
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        /* We should never be setting status to 0. */
        BUG_ON(status == 0);
-       return iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS);
+       iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS);
 }
 
 static void vp_reset(struct virtio_device *vdev)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        /* 0 status means a reset. */
-       return iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS);
+       iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS);
 }
 
 /* the notify function used when creating a virt queue */
@@ -177,6 +178,7 @@ static irqreturn_t vp_interrupt(int irq, void *opaque)
        struct virtio_pci_device *vp_dev = opaque;
        struct virtio_pci_vq_info *info;
        irqreturn_t ret = IRQ_NONE;
+       unsigned long flags;
        u8 isr;
 
        /* reading the ISR has the effect of also clearing it so it's very
@@ -197,12 +199,12 @@ static irqreturn_t vp_interrupt(int irq, void *opaque)
                        drv->config_changed(&vp_dev->vdev);
        }
 
-       spin_lock(&vp_dev->lock);
+       spin_lock_irqsave(&vp_dev->lock, flags);
        list_for_each_entry(info, &vp_dev->virtqueues, node) {
                if (vring_interrupt(irq, info->vq) == IRQ_HANDLED)
                        ret = IRQ_HANDLED;
        }
-       spin_unlock(&vp_dev->lock);
+       spin_unlock_irqrestore(&vp_dev->lock, flags);
 
        return ret;
 }
@@ -214,6 +216,7 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index,
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        struct virtio_pci_vq_info *info;
        struct virtqueue *vq;
+       unsigned long flags;
        u16 num;
        int err;
 
@@ -255,9 +258,9 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index,
        vq->priv = info;
        info->vq = vq;
 
-       spin_lock(&vp_dev->lock);
+       spin_lock_irqsave(&vp_dev->lock, flags);
        list_add(&info->node, &vp_dev->virtqueues);
-       spin_unlock(&vp_dev->lock);
+       spin_unlock_irqrestore(&vp_dev->lock, flags);
 
        return vq;
 
@@ -274,10 +277,11 @@ static void vp_del_vq(struct virtqueue *vq)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
        struct virtio_pci_vq_info *info = vq->priv;
+       unsigned long flags;
 
-       spin_lock(&vp_dev->lock);
+       spin_lock_irqsave(&vp_dev->lock, flags);
        list_del(&info->node);
-       spin_unlock(&vp_dev->lock);
+       spin_unlock_irqrestore(&vp_dev->lock, flags);
 
        vring_del_virtqueue(vq);
 
@@ -290,7 +294,6 @@ static void vp_del_vq(struct virtqueue *vq)
 }
 
 static struct virtio_config_ops virtio_pci_config_ops = {
-       .feature        = vp_feature,
        .get            = vp_get,
        .set            = vp_set,
        .get_status     = vp_get_status,
@@ -298,6 +301,8 @@ static struct virtio_config_ops virtio_pci_config_ops = {
        .reset          = vp_reset,
        .find_vq        = vp_find_vq,
        .del_vq         = vp_del_vq,
+       .get_features   = vp_get_features,
+       .finalize_features = vp_finalize_features,
 };
 
 /* the PCI probing function */
@@ -322,10 +327,6 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,
        if (vp_dev == NULL)
                return -ENOMEM;
 
-       snprintf(vp_dev->vdev.dev.bus_id, BUS_ID_SIZE, "virtio%d", dev_index);
-       vp_dev->vdev.index = dev_index;
-       dev_index++;
-
        vp_dev->vdev.dev.parent = &virtio_pci_root;
        vp_dev->vdev.config = &virtio_pci_config_ops;
        vp_dev->pci_dev = pci_dev;
@@ -385,6 +386,7 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev)
 {
        struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
 
+       unregister_virtio_device(&vp_dev->vdev);
        free_irq(pci_dev->irq, vp_dev);
        pci_set_drvdata(pci_dev, NULL);
        pci_iounmap(pci_dev, vp_dev->ioaddr);