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;
.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->set_features() implementation */
+static void vp_set_features(struct virtio_device *vdev, u32 features)
+{
+ struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+
+ iowrite32(features, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES);
}
/* virtio config->get() implementation */
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;
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;
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 */
}
static struct virtio_config_ops virtio_pci_config_ops = {
- .feature = vp_feature,
.get = vp_get,
.set = vp_set,
.get_status = vp_get_status,
.reset = vp_reset,
.find_vq = vp_find_vq,
.del_vq = vp_del_vq,
+ .get_features = vp_get_features,
+ .set_features = vp_set_features,
};
/* the PCI probing function */
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;
{
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);