diff options
Diffstat (limited to 'drivers/virtio')
-rw-r--r-- | drivers/virtio/virtio.c | 2 | ||||
-rw-r--r-- | drivers/virtio/virtio_balloon.c | 13 | ||||
-rw-r--r-- | drivers/virtio/virtio_pci.c | 43 | ||||
-rw-r--r-- | drivers/virtio/virtio_ring.c | 3 |
4 files changed, 41 insertions, 20 deletions
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 5b78fd0aff0a..018c070a357f 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c | |||
@@ -176,7 +176,7 @@ int register_virtio_device(struct virtio_device *dev) | |||
176 | 176 | ||
177 | /* Assign a unique device index and hence name. */ | 177 | /* Assign a unique device index and hence name. */ |
178 | dev->index = dev_index++; | 178 | dev->index = dev_index++; |
179 | sprintf(dev->dev.bus_id, "virtio%u", dev->index); | 179 | dev_set_name(&dev->dev, "virtio%u", dev->index); |
180 | 180 | ||
181 | /* We always start by resetting the device, in case a previous | 181 | /* We always start by resetting the device, in case a previous |
182 | * driver messed it up. This also tests that code path a little. */ | 182 | * driver messed it up. This also tests that code path a little. */ |
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 62eab43152d2..59268266b79a 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -56,6 +56,15 @@ static struct virtio_device_id id_table[] = { | |||
56 | { 0 }, | 56 | { 0 }, |
57 | }; | 57 | }; |
58 | 58 | ||
59 | static u32 page_to_balloon_pfn(struct page *page) | ||
60 | { | ||
61 | unsigned long pfn = page_to_pfn(page); | ||
62 | |||
63 | BUILD_BUG_ON(PAGE_SHIFT < VIRTIO_BALLOON_PFN_SHIFT); | ||
64 | /* Convert pfn from Linux page size to balloon page size. */ | ||
65 | return pfn >> (PAGE_SHIFT - VIRTIO_BALLOON_PFN_SHIFT); | ||
66 | } | ||
67 | |||
59 | static void balloon_ack(struct virtqueue *vq) | 68 | static void balloon_ack(struct virtqueue *vq) |
60 | { | 69 | { |
61 | struct virtio_balloon *vb; | 70 | struct virtio_balloon *vb; |
@@ -99,7 +108,7 @@ static void fill_balloon(struct virtio_balloon *vb, size_t num) | |||
99 | msleep(200); | 108 | msleep(200); |
100 | break; | 109 | break; |
101 | } | 110 | } |
102 | vb->pfns[vb->num_pfns] = page_to_pfn(page); | 111 | vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page); |
103 | totalram_pages--; | 112 | totalram_pages--; |
104 | vb->num_pages++; | 113 | vb->num_pages++; |
105 | list_add(&page->lru, &vb->pages); | 114 | list_add(&page->lru, &vb->pages); |
@@ -132,7 +141,7 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num) | |||
132 | for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { | 141 | for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { |
133 | page = list_first_entry(&vb->pages, struct page, lru); | 142 | page = list_first_entry(&vb->pages, struct page, lru); |
134 | list_del(&page->lru); | 143 | list_del(&page->lru); |
135 | vb->pfns[vb->num_pfns] = page_to_pfn(page); | 144 | vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page); |
136 | vb->num_pages--; | 145 | vb->num_pages--; |
137 | } | 146 | } |
138 | 147 | ||
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index c7dc37c7cce9..265fdf2d1276 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c | |||
@@ -75,7 +75,7 @@ MODULE_DEVICE_TABLE(pci, virtio_pci_id_table); | |||
75 | * would make more sense for virtio to not insist on having it's own device. */ | 75 | * would make more sense for virtio to not insist on having it's own device. */ |
76 | static struct device virtio_pci_root = { | 76 | static struct device virtio_pci_root = { |
77 | .parent = NULL, | 77 | .parent = NULL, |
78 | .bus_id = "virtio-pci", | 78 | .init_name = "virtio-pci", |
79 | }; | 79 | }; |
80 | 80 | ||
81 | /* Convert a generic virtio device to our structure */ | 81 | /* Convert a generic virtio device to our structure */ |
@@ -216,7 +216,7 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index, | |||
216 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | 216 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); |
217 | struct virtio_pci_vq_info *info; | 217 | struct virtio_pci_vq_info *info; |
218 | struct virtqueue *vq; | 218 | struct virtqueue *vq; |
219 | unsigned long flags; | 219 | unsigned long flags, size; |
220 | u16 num; | 220 | u16 num; |
221 | int err; | 221 | int err; |
222 | 222 | ||
@@ -237,19 +237,20 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index, | |||
237 | info->queue_index = index; | 237 | info->queue_index = index; |
238 | info->num = num; | 238 | info->num = num; |
239 | 239 | ||
240 | info->queue = kzalloc(PAGE_ALIGN(vring_size(num,PAGE_SIZE)), GFP_KERNEL); | 240 | size = PAGE_ALIGN(vring_size(num, VIRTIO_PCI_VRING_ALIGN)); |
241 | info->queue = alloc_pages_exact(size, GFP_KERNEL|__GFP_ZERO); | ||
241 | if (info->queue == NULL) { | 242 | if (info->queue == NULL) { |
242 | err = -ENOMEM; | 243 | err = -ENOMEM; |
243 | goto out_info; | 244 | goto out_info; |
244 | } | 245 | } |
245 | 246 | ||
246 | /* activate the queue */ | 247 | /* activate the queue */ |
247 | iowrite32(virt_to_phys(info->queue) >> PAGE_SHIFT, | 248 | iowrite32(virt_to_phys(info->queue) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT, |
248 | vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); | 249 | vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); |
249 | 250 | ||
250 | /* create the vring */ | 251 | /* create the vring */ |
251 | vq = vring_new_virtqueue(info->num, vdev, info->queue, | 252 | vq = vring_new_virtqueue(info->num, VIRTIO_PCI_VRING_ALIGN, |
252 | vp_notify, callback); | 253 | vdev, info->queue, vp_notify, callback); |
253 | if (!vq) { | 254 | if (!vq) { |
254 | err = -ENOMEM; | 255 | err = -ENOMEM; |
255 | goto out_activate_queue; | 256 | goto out_activate_queue; |
@@ -266,7 +267,7 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index, | |||
266 | 267 | ||
267 | out_activate_queue: | 268 | out_activate_queue: |
268 | iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); | 269 | iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); |
269 | kfree(info->queue); | 270 | free_pages_exact(info->queue, size); |
270 | out_info: | 271 | out_info: |
271 | kfree(info); | 272 | kfree(info); |
272 | return ERR_PTR(err); | 273 | return ERR_PTR(err); |
@@ -277,7 +278,7 @@ static void vp_del_vq(struct virtqueue *vq) | |||
277 | { | 278 | { |
278 | struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); | 279 | struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); |
279 | struct virtio_pci_vq_info *info = vq->priv; | 280 | struct virtio_pci_vq_info *info = vq->priv; |
280 | unsigned long flags; | 281 | unsigned long flags, size; |
281 | 282 | ||
282 | spin_lock_irqsave(&vp_dev->lock, flags); | 283 | spin_lock_irqsave(&vp_dev->lock, flags); |
283 | list_del(&info->node); | 284 | list_del(&info->node); |
@@ -289,7 +290,8 @@ static void vp_del_vq(struct virtqueue *vq) | |||
289 | iowrite16(info->queue_index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); | 290 | iowrite16(info->queue_index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); |
290 | iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); | 291 | iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); |
291 | 292 | ||
292 | kfree(info->queue); | 293 | size = PAGE_ALIGN(vring_size(info->num, VIRTIO_PCI_VRING_ALIGN)); |
294 | free_pages_exact(info->queue, size); | ||
293 | kfree(info); | 295 | kfree(info); |
294 | } | 296 | } |
295 | 297 | ||
@@ -305,6 +307,20 @@ static struct virtio_config_ops virtio_pci_config_ops = { | |||
305 | .finalize_features = vp_finalize_features, | 307 | .finalize_features = vp_finalize_features, |
306 | }; | 308 | }; |
307 | 309 | ||
310 | static void virtio_pci_release_dev(struct device *_d) | ||
311 | { | ||
312 | struct virtio_device *dev = container_of(_d, struct virtio_device, dev); | ||
313 | struct virtio_pci_device *vp_dev = to_vp_device(dev); | ||
314 | struct pci_dev *pci_dev = vp_dev->pci_dev; | ||
315 | |||
316 | free_irq(pci_dev->irq, vp_dev); | ||
317 | pci_set_drvdata(pci_dev, NULL); | ||
318 | pci_iounmap(pci_dev, vp_dev->ioaddr); | ||
319 | pci_release_regions(pci_dev); | ||
320 | pci_disable_device(pci_dev); | ||
321 | kfree(vp_dev); | ||
322 | } | ||
323 | |||
308 | /* the PCI probing function */ | 324 | /* the PCI probing function */ |
309 | static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, | 325 | static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, |
310 | const struct pci_device_id *id) | 326 | const struct pci_device_id *id) |
@@ -328,6 +344,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, | |||
328 | return -ENOMEM; | 344 | return -ENOMEM; |
329 | 345 | ||
330 | vp_dev->vdev.dev.parent = &virtio_pci_root; | 346 | vp_dev->vdev.dev.parent = &virtio_pci_root; |
347 | vp_dev->vdev.dev.release = virtio_pci_release_dev; | ||
331 | vp_dev->vdev.config = &virtio_pci_config_ops; | 348 | vp_dev->vdev.config = &virtio_pci_config_ops; |
332 | vp_dev->pci_dev = pci_dev; | 349 | vp_dev->pci_dev = pci_dev; |
333 | INIT_LIST_HEAD(&vp_dev->virtqueues); | 350 | INIT_LIST_HEAD(&vp_dev->virtqueues); |
@@ -357,7 +374,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, | |||
357 | 374 | ||
358 | /* register a handler for the queue with the PCI device's interrupt */ | 375 | /* register a handler for the queue with the PCI device's interrupt */ |
359 | err = request_irq(vp_dev->pci_dev->irq, vp_interrupt, IRQF_SHARED, | 376 | err = request_irq(vp_dev->pci_dev->irq, vp_interrupt, IRQF_SHARED, |
360 | vp_dev->vdev.dev.bus_id, vp_dev); | 377 | dev_name(&vp_dev->vdev.dev), vp_dev); |
361 | if (err) | 378 | if (err) |
362 | goto out_set_drvdata; | 379 | goto out_set_drvdata; |
363 | 380 | ||
@@ -387,12 +404,6 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev) | |||
387 | struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); | 404 | struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); |
388 | 405 | ||
389 | unregister_virtio_device(&vp_dev->vdev); | 406 | unregister_virtio_device(&vp_dev->vdev); |
390 | free_irq(pci_dev->irq, vp_dev); | ||
391 | pci_set_drvdata(pci_dev, NULL); | ||
392 | pci_iounmap(pci_dev, vp_dev->ioaddr); | ||
393 | pci_release_regions(pci_dev); | ||
394 | pci_disable_device(pci_dev); | ||
395 | kfree(vp_dev); | ||
396 | } | 407 | } |
397 | 408 | ||
398 | #ifdef CONFIG_PM | 409 | #ifdef CONFIG_PM |
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 6eb5303fed11..5777196bf6c9 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
@@ -274,6 +274,7 @@ static struct virtqueue_ops vring_vq_ops = { | |||
274 | }; | 274 | }; |
275 | 275 | ||
276 | struct virtqueue *vring_new_virtqueue(unsigned int num, | 276 | struct virtqueue *vring_new_virtqueue(unsigned int num, |
277 | unsigned int vring_align, | ||
277 | struct virtio_device *vdev, | 278 | struct virtio_device *vdev, |
278 | void *pages, | 279 | void *pages, |
279 | void (*notify)(struct virtqueue *), | 280 | void (*notify)(struct virtqueue *), |
@@ -292,7 +293,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int num, | |||
292 | if (!vq) | 293 | if (!vq) |
293 | return NULL; | 294 | return NULL; |
294 | 295 | ||
295 | vring_init(&vq->vring, num, pages, PAGE_SIZE); | 296 | vring_init(&vq->vring, num, pages, vring_align); |
296 | vq->vq.callback = callback; | 297 | vq->vq.callback = callback; |
297 | vq->vq.vdev = vdev; | 298 | vq->vq.vdev = vdev; |
298 | vq->vq.vq_ops = &vring_vq_ops; | 299 | vq->vq.vq_ops = &vring_vq_ops; |