aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/virtio
diff options
context:
space:
mode:
authorHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-07-27 07:54:08 -0400
committerHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-07-27 07:54:08 -0400
commiteda3d8f5604860aae1bb9996bb5efc4213778369 (patch)
tree9d3887d2665bcc5f5abf200758794545c7b2c69b /drivers/virtio
parent87a9f704658a40940e740b1d73d861667e9164d3 (diff)
parent8be1a6d6c77ab4532e4476fdb8177030ef48b52c (diff)
Merge commit 'upstream/master'
Diffstat (limited to 'drivers/virtio')
-rw-r--r--drivers/virtio/virtio.c26
-rw-r--r--drivers/virtio/virtio_pci.c13
-rw-r--r--drivers/virtio/virtio_ring.c23
3 files changed, 45 insertions, 17 deletions
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 7084e7e146c0..5b78fd0aff0a 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -71,13 +71,6 @@ static int virtio_uevent(struct device *_dv, struct kobj_uevent_env *env)
71 dev->id.device, dev->id.vendor); 71 dev->id.device, dev->id.vendor);
72} 72}
73 73
74static struct bus_type virtio_bus = {
75 .name = "virtio",
76 .match = virtio_dev_match,
77 .dev_attrs = virtio_dev_attrs,
78 .uevent = virtio_uevent,
79};
80
81static void add_status(struct virtio_device *dev, unsigned status) 74static void add_status(struct virtio_device *dev, unsigned status)
82{ 75{
83 dev->config->set_status(dev, dev->config->get_status(dev) | status); 76 dev->config->set_status(dev, dev->config->get_status(dev) | status);
@@ -120,12 +113,16 @@ static int virtio_dev_probe(struct device *_d)
120 set_bit(f, dev->features); 113 set_bit(f, dev->features);
121 } 114 }
122 115
116 /* Transport features always preserved to pass to finalize_features. */
117 for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++)
118 if (device_features & (1 << i))
119 set_bit(i, dev->features);
120
123 err = drv->probe(dev); 121 err = drv->probe(dev);
124 if (err) 122 if (err)
125 add_status(dev, VIRTIO_CONFIG_S_FAILED); 123 add_status(dev, VIRTIO_CONFIG_S_FAILED);
126 else { 124 else {
127 /* They should never have set feature bits beyond 32 */ 125 dev->config->finalize_features(dev);
128 dev->config->set_features(dev, dev->features[0]);
129 add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); 126 add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
130 } 127 }
131 return err; 128 return err;
@@ -147,13 +144,20 @@ static int virtio_dev_remove(struct device *_d)
147 return 0; 144 return 0;
148} 145}
149 146
147static struct bus_type virtio_bus = {
148 .name = "virtio",
149 .match = virtio_dev_match,
150 .dev_attrs = virtio_dev_attrs,
151 .uevent = virtio_uevent,
152 .probe = virtio_dev_probe,
153 .remove = virtio_dev_remove,
154};
155
150int register_virtio_driver(struct virtio_driver *driver) 156int register_virtio_driver(struct virtio_driver *driver)
151{ 157{
152 /* Catch this early. */ 158 /* Catch this early. */
153 BUG_ON(driver->feature_table_size && !driver->feature_table); 159 BUG_ON(driver->feature_table_size && !driver->feature_table);
154 driver->driver.bus = &virtio_bus; 160 driver->driver.bus = &virtio_bus;
155 driver->driver.probe = virtio_dev_probe;
156 driver->driver.remove = virtio_dev_remove;
157 return driver_register(&driver->driver); 161 return driver_register(&driver->driver);
158} 162}
159EXPORT_SYMBOL_GPL(register_virtio_driver); 163EXPORT_SYMBOL_GPL(register_virtio_driver);
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index eae7236310e4..c7dc37c7cce9 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -94,12 +94,17 @@ static u32 vp_get_features(struct virtio_device *vdev)
94 return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES); 94 return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES);
95} 95}
96 96
97/* virtio config->set_features() implementation */ 97/* virtio config->finalize_features() implementation */
98static void vp_set_features(struct virtio_device *vdev, u32 features) 98static void vp_finalize_features(struct virtio_device *vdev)
99{ 99{
100 struct virtio_pci_device *vp_dev = to_vp_device(vdev); 100 struct virtio_pci_device *vp_dev = to_vp_device(vdev);
101 101
102 iowrite32(features, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES); 102 /* Give virtio_ring a chance to accept features. */
103 vring_transport_features(vdev);
104
105 /* We only support 32 feature bits. */
106 BUILD_BUG_ON(ARRAY_SIZE(vdev->features) != 1);
107 iowrite32(vdev->features[0], vp_dev->ioaddr+VIRTIO_PCI_GUEST_FEATURES);
103} 108}
104 109
105/* virtio config->get() implementation */ 110/* virtio config->get() implementation */
@@ -297,7 +302,7 @@ static struct virtio_config_ops virtio_pci_config_ops = {
297 .find_vq = vp_find_vq, 302 .find_vq = vp_find_vq,
298 .del_vq = vp_del_vq, 303 .del_vq = vp_del_vq,
299 .get_features = vp_get_features, 304 .get_features = vp_get_features,
300 .set_features = vp_set_features, 305 .finalize_features = vp_finalize_features,
301}; 306};
302 307
303/* the PCI probing function */ 308/* the PCI probing function */
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 72bf8bc09014..6eb5303fed11 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -18,6 +18,7 @@
18 */ 18 */
19#include <linux/virtio.h> 19#include <linux/virtio.h>
20#include <linux/virtio_ring.h> 20#include <linux/virtio_ring.h>
21#include <linux/virtio_config.h>
21#include <linux/device.h> 22#include <linux/device.h>
22 23
23#ifdef DEBUG 24#ifdef DEBUG
@@ -87,8 +88,11 @@ static int vring_add_buf(struct virtqueue *_vq,
87 if (vq->num_free < out + in) { 88 if (vq->num_free < out + in) {
88 pr_debug("Can't add buf len %i - avail = %i\n", 89 pr_debug("Can't add buf len %i - avail = %i\n",
89 out + in, vq->num_free); 90 out + in, vq->num_free);
90 /* We notify *even if* VRING_USED_F_NO_NOTIFY is set here. */ 91 /* FIXME: for historical reasons, we force a notify here if
91 vq->notify(&vq->vq); 92 * there are outgoing parts to the buffer. Presumably the
93 * host should service the ring ASAP. */
94 if (out)
95 vq->notify(&vq->vq);
92 END_USE(vq); 96 END_USE(vq);
93 return -ENOSPC; 97 return -ENOSPC;
94 } 98 }
@@ -320,4 +324,19 @@ void vring_del_virtqueue(struct virtqueue *vq)
320} 324}
321EXPORT_SYMBOL_GPL(vring_del_virtqueue); 325EXPORT_SYMBOL_GPL(vring_del_virtqueue);
322 326
327/* Manipulates transport-specific feature bits. */
328void vring_transport_features(struct virtio_device *vdev)
329{
330 unsigned int i;
331
332 for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++) {
333 switch (i) {
334 default:
335 /* We don't understand this bit. */
336 clear_bit(i, vdev->features);
337 }
338 }
339}
340EXPORT_SYMBOL_GPL(vring_transport_features);
341
323MODULE_LICENSE("GPL"); 342MODULE_LICENSE("GPL");