提交 b769f579 编写于 作者: R Rusty Russell

virtio: set device index in common code.

Anthony Liguori points out that three different transports use the virtio code,
but each one keeps its own counter to set the virtio_device's index field.  In
theory (though not in current practice) this means that names could be
duplicated, and that risk grows as more transports are created.

So we move the selection of the unique virtio_device.index into the common code
in virtio.c, which has the side-benefit of removing duplicate code.

The only complexity is that lguest and S/390 use the index to uniquely identify
the device in case of catastrophic failure before register_virtio_device() is
called: now we use the offset within the descriptor page as a unique identifier
for the printks.
Signed-off-by: NRusty Russell <rusty@rustcorp.com.au>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Carsten Otte <cotte@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Chris Lalancette <clalance@redhat.com>
Cc: Anthony Liguori <anthony@codemonkey.ws>
上级 5610bd15
...@@ -20,9 +20,6 @@ ...@@ -20,9 +20,6 @@
/* The pointer to our (page) of device descriptions. */ /* The pointer to our (page) of device descriptions. */
static void *lguest_devices; static void *lguest_devices;
/* Unique numbering for lguest devices. */
static unsigned int dev_index;
/* For Guests, device memory can be used as normal memory, so we cast away the /* For Guests, device memory can be used as normal memory, so we cast away the
* __iomem to quieten sparse. */ * __iomem to quieten sparse. */
static inline void *lguest_map(unsigned long phys_addr, unsigned long pages) static inline void *lguest_map(unsigned long phys_addr, unsigned long pages)
...@@ -325,8 +322,10 @@ static struct device lguest_root = { ...@@ -325,8 +322,10 @@ static struct device lguest_root = {
* As Andrew Tridgell says, "Untested code is buggy code". * As Andrew Tridgell says, "Untested code is buggy code".
* *
* It's worth reading this carefully: we start with a pointer to the new device * It's worth reading this carefully: we start with a pointer to the new device
* descriptor in the "lguest_devices" page. */ * descriptor in the "lguest_devices" page, and the offset into the device
static void add_lguest_device(struct lguest_device_desc *d) * descriptor page so we can uniquely identify it if things go badly wrong. */
static void add_lguest_device(struct lguest_device_desc *d,
unsigned int offset)
{ {
struct lguest_device *ldev; struct lguest_device *ldev;
...@@ -334,18 +333,14 @@ static void add_lguest_device(struct lguest_device_desc *d) ...@@ -334,18 +333,14 @@ static void add_lguest_device(struct lguest_device_desc *d)
* it. */ * it. */
ldev = kzalloc(sizeof(*ldev), GFP_KERNEL); ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
if (!ldev) { if (!ldev) {
printk(KERN_EMERG "Cannot allocate lguest dev %u\n", printk(KERN_EMERG "Cannot allocate lguest dev %u type %u\n",
dev_index++); offset, d->type);
return; return;
} }
/* This devices' parent is the lguest/ dir. */ /* This devices' parent is the lguest/ dir. */
ldev->vdev.dev.parent = &lguest_root; ldev->vdev.dev.parent = &lguest_root;
/* We have a unique device index thanks to the dev_index counter. */ /* We have a unique device index thanks to the dev_index counter. */
ldev->vdev.index = dev_index++;
/* The device type comes straight from the descriptor. There's also a
* device vendor field in the virtio_device struct, which we leave as
* 0. */
ldev->vdev.id.device = d->type; ldev->vdev.id.device = d->type;
/* We have a simple set of routines for querying the device's /* We have a simple set of routines for querying the device's
* configuration information and setting its status. */ * configuration information and setting its status. */
...@@ -357,8 +352,8 @@ static void add_lguest_device(struct lguest_device_desc *d) ...@@ -357,8 +352,8 @@ static void add_lguest_device(struct lguest_device_desc *d)
* virtio_device and calls device_register(). This makes the bus * virtio_device and calls device_register(). This makes the bus
* infrastructure look for a matching driver. */ * infrastructure look for a matching driver. */
if (register_virtio_device(&ldev->vdev) != 0) { if (register_virtio_device(&ldev->vdev) != 0) {
printk(KERN_ERR "Failed to register lguest device %u\n", printk(KERN_ERR "Failed to register lguest dev %u type %u\n",
ldev->vdev.index); offset, d->type);
kfree(ldev); kfree(ldev);
} }
} }
...@@ -379,7 +374,7 @@ static void scan_devices(void) ...@@ -379,7 +374,7 @@ static void scan_devices(void)
break; break;
printk("Device at %i has size %u\n", i, desc_size(d)); printk("Device at %i has size %u\n", i, desc_size(d));
add_lguest_device(d); add_lguest_device(d, i);
} }
} }
......
...@@ -31,11 +31,6 @@ ...@@ -31,11 +31,6 @@
*/ */
static void *kvm_devices; static void *kvm_devices;
/*
* Unique numbering for kvm devices.
*/
static unsigned int dev_index;
struct kvm_device { struct kvm_device {
struct virtio_device vdev; struct virtio_device vdev;
struct kvm_device_desc *desc; struct kvm_device_desc *desc;
...@@ -250,26 +245,25 @@ static struct device kvm_root = { ...@@ -250,26 +245,25 @@ static struct device kvm_root = {
* adds a new device and register it with virtio * adds a new device and register it with virtio
* appropriate drivers are loaded by the device model * appropriate drivers are loaded by the device model
*/ */
static void add_kvm_device(struct kvm_device_desc *d) static void add_kvm_device(struct kvm_device_desc *d, unsigned int offset)
{ {
struct kvm_device *kdev; struct kvm_device *kdev;
kdev = kzalloc(sizeof(*kdev), GFP_KERNEL); kdev = kzalloc(sizeof(*kdev), GFP_KERNEL);
if (!kdev) { if (!kdev) {
printk(KERN_EMERG "Cannot allocate kvm dev %u\n", printk(KERN_EMERG "Cannot allocate kvm dev %u type %u\n",
dev_index++); offset, d->type);
return; return;
} }
kdev->vdev.dev.parent = &kvm_root; kdev->vdev.dev.parent = &kvm_root;
kdev->vdev.index = dev_index++;
kdev->vdev.id.device = d->type; kdev->vdev.id.device = d->type;
kdev->vdev.config = &kvm_vq_configspace_ops; kdev->vdev.config = &kvm_vq_configspace_ops;
kdev->desc = d; kdev->desc = d;
if (register_virtio_device(&kdev->vdev) != 0) { if (register_virtio_device(&kdev->vdev) != 0) {
printk(KERN_ERR "Failed to register kvm device %u\n", printk(KERN_ERR "Failed to register kvm device %u type %u\n",
kdev->vdev.index); offset, d->type);
kfree(kdev); kfree(kdev);
} }
} }
...@@ -289,7 +283,7 @@ static void scan_devices(void) ...@@ -289,7 +283,7 @@ static void scan_devices(void)
if (d->type == 0) if (d->type == 0)
break; break;
add_kvm_device(d); add_kvm_device(d, i);
} }
} }
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/virtio_config.h> #include <linux/virtio_config.h>
/* Unique numbering for virtio devices. */
static unsigned int dev_index;
static ssize_t device_show(struct device *_d, static ssize_t device_show(struct device *_d,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
...@@ -166,6 +169,9 @@ int register_virtio_device(struct virtio_device *dev) ...@@ -166,6 +169,9 @@ int register_virtio_device(struct virtio_device *dev)
int err; int err;
dev->dev.bus = &virtio_bus; dev->dev.bus = &virtio_bus;
/* Assign a unique device index and hence name. */
dev->index = dev_index++;
sprintf(dev->dev.bus_id, "virtio%u", dev->index); sprintf(dev->dev.bus_id, "virtio%u", dev->index);
/* We always start by resetting the device, in case a previous /* We always start by resetting the device, in case a previous
......
...@@ -78,9 +78,6 @@ static struct device virtio_pci_root = { ...@@ -78,9 +78,6 @@ static struct device virtio_pci_root = {
.bus_id = "virtio-pci", .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 */ /* Convert a generic virtio device to our structure */
static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev) static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev)
{ {
...@@ -325,9 +322,6 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, ...@@ -325,9 +322,6 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,
if (vp_dev == NULL) if (vp_dev == NULL)
return -ENOMEM; return -ENOMEM;
vp_dev->vdev.index = dev_index;
dev_index++;
vp_dev->vdev.dev.parent = &virtio_pci_root; vp_dev->vdev.dev.parent = &virtio_pci_root;
vp_dev->vdev.config = &virtio_pci_config_ops; vp_dev->vdev.config = &virtio_pci_config_ops;
vp_dev->pci_dev = pci_dev; vp_dev->pci_dev = pci_dev;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册