aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/virtio/virtio_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/virtio/virtio_pci.c')
-rw-r--r--drivers/virtio/virtio_pci.c56
1 files changed, 31 insertions, 25 deletions
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index 6f3db1f89654..6a7b8bff51e5 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -31,6 +31,23 @@ MODULE_DESCRIPTION("virtio-pci");
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32MODULE_VERSION("1"); 32MODULE_VERSION("1");
33 33
34struct virtio_pci_vq_info {
35 /* the actual virtqueue */
36 struct virtqueue *vq;
37
38 /* the number of entries in the queue */
39 int num;
40
41 /* the virtual address of the ring queue */
42 void *queue;
43
44 /* the list node for the virtqueues list */
45 struct list_head node;
46
47 /* MSI-X vector (or none) */
48 unsigned msix_vector;
49};
50
34/* Our device structure */ 51/* Our device structure */
35struct virtio_pci_device { 52struct virtio_pci_device {
36 struct virtio_device vdev; 53 struct virtio_device vdev;
@@ -46,6 +63,9 @@ struct virtio_pci_device {
46 spinlock_t lock; 63 spinlock_t lock;
47 struct list_head virtqueues; 64 struct list_head virtqueues;
48 65
66 /* array of all queues for house-keeping */
67 struct virtio_pci_vq_info **vqs;
68
49 /* MSI-X support */ 69 /* MSI-X support */
50 int msix_enabled; 70 int msix_enabled;
51 int intx_enabled; 71 int intx_enabled;
@@ -71,23 +91,6 @@ enum {
71 VP_MSIX_VQ_VECTOR = 1, 91 VP_MSIX_VQ_VECTOR = 1,
72}; 92};
73 93
74struct virtio_pci_vq_info {
75 /* the actual virtqueue */
76 struct virtqueue *vq;
77
78 /* the number of entries in the queue */
79 int num;
80
81 /* the virtual address of the ring queue */
82 void *queue;
83
84 /* the list node for the virtqueues list */
85 struct list_head node;
86
87 /* MSI-X vector (or none) */
88 unsigned msix_vector;
89};
90
91/* Qumranet donated their vendor ID for devices 0x1000 thru 0x10FF. */ 94/* Qumranet donated their vendor ID for devices 0x1000 thru 0x10FF. */
92static const struct pci_device_id virtio_pci_id_table[] = { 95static const struct pci_device_id virtio_pci_id_table[] = {
93 { PCI_DEVICE(0x1af4, PCI_ANY_ID) }, 96 { PCI_DEVICE(0x1af4, PCI_ANY_ID) },
@@ -434,7 +437,6 @@ static struct virtqueue *setup_vq(struct virtio_device *vdev, unsigned index,
434 goto out_activate_queue; 437 goto out_activate_queue;
435 } 438 }
436 439
437 vq->priv = info;
438 info->vq = vq; 440 info->vq = vq;
439 441
440 if (msix_vec != VIRTIO_MSI_NO_VECTOR) { 442 if (msix_vec != VIRTIO_MSI_NO_VECTOR) {
@@ -454,6 +456,7 @@ static struct virtqueue *setup_vq(struct virtio_device *vdev, unsigned index,
454 INIT_LIST_HEAD(&info->node); 456 INIT_LIST_HEAD(&info->node);
455 } 457 }
456 458
459 vp_dev->vqs[index] = info;
457 return vq; 460 return vq;
458 461
459out_assign: 462out_assign:
@@ -469,7 +472,7 @@ out_info:
469static void vp_del_vq(struct virtqueue *vq) 472static void vp_del_vq(struct virtqueue *vq)
470{ 473{
471 struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); 474 struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
472 struct virtio_pci_vq_info *info = vq->priv; 475 struct virtio_pci_vq_info *info = vp_dev->vqs[vq->index];
473 unsigned long flags, size; 476 unsigned long flags, size;
474 477
475 spin_lock_irqsave(&vp_dev->lock, flags); 478 spin_lock_irqsave(&vp_dev->lock, flags);
@@ -503,7 +506,7 @@ static void vp_del_vqs(struct virtio_device *vdev)
503 struct virtio_pci_vq_info *info; 506 struct virtio_pci_vq_info *info;
504 507
505 list_for_each_entry_safe(vq, n, &vdev->vqs, list) { 508 list_for_each_entry_safe(vq, n, &vdev->vqs, list) {
506 info = vq->priv; 509 info = vp_dev->vqs[vq->index];
507 if (vp_dev->per_vq_vectors && 510 if (vp_dev->per_vq_vectors &&
508 info->msix_vector != VIRTIO_MSI_NO_VECTOR) 511 info->msix_vector != VIRTIO_MSI_NO_VECTOR)
509 free_irq(vp_dev->msix_entries[info->msix_vector].vector, 512 free_irq(vp_dev->msix_entries[info->msix_vector].vector,
@@ -513,6 +516,7 @@ static void vp_del_vqs(struct virtio_device *vdev)
513 vp_dev->per_vq_vectors = false; 516 vp_dev->per_vq_vectors = false;
514 517
515 vp_free_vectors(vdev); 518 vp_free_vectors(vdev);
519 kfree(vp_dev->vqs);
516} 520}
517 521
518static int vp_try_to_find_vqs(struct virtio_device *vdev, unsigned nvqs, 522static int vp_try_to_find_vqs(struct virtio_device *vdev, unsigned nvqs,
@@ -526,11 +530,15 @@ static int vp_try_to_find_vqs(struct virtio_device *vdev, unsigned nvqs,
526 u16 msix_vec; 530 u16 msix_vec;
527 int i, err, nvectors, allocated_vectors; 531 int i, err, nvectors, allocated_vectors;
528 532
533 vp_dev->vqs = kmalloc(nvqs * sizeof *vp_dev->vqs, GFP_KERNEL);
534 if (!vp_dev->vqs)
535 return -ENOMEM;
536
529 if (!use_msix) { 537 if (!use_msix) {
530 /* Old style: one normal interrupt for change and all vqs. */ 538 /* Old style: one normal interrupt for change and all vqs. */
531 err = vp_request_intx(vdev); 539 err = vp_request_intx(vdev);
532 if (err) 540 if (err)
533 goto error_request; 541 goto error_find;
534 } else { 542 } else {
535 if (per_vq_vectors) { 543 if (per_vq_vectors) {
536 /* Best option: one for change interrupt, one per vq. */ 544 /* Best option: one for change interrupt, one per vq. */
@@ -545,7 +553,7 @@ static int vp_try_to_find_vqs(struct virtio_device *vdev, unsigned nvqs,
545 553
546 err = vp_request_msix_vectors(vdev, nvectors, per_vq_vectors); 554 err = vp_request_msix_vectors(vdev, nvectors, per_vq_vectors);
547 if (err) 555 if (err)
548 goto error_request; 556 goto error_find;
549 } 557 }
550 558
551 vp_dev->per_vq_vectors = per_vq_vectors; 559 vp_dev->per_vq_vectors = per_vq_vectors;
@@ -587,8 +595,6 @@ static int vp_try_to_find_vqs(struct virtio_device *vdev, unsigned nvqs,
587 595
588error_find: 596error_find:
589 vp_del_vqs(vdev); 597 vp_del_vqs(vdev);
590
591error_request:
592 return err; 598 return err;
593} 599}
594 600
@@ -630,7 +636,7 @@ static int vp_set_vq_affinity(struct virtqueue *vq, int cpu)
630{ 636{
631 struct virtio_device *vdev = vq->vdev; 637 struct virtio_device *vdev = vq->vdev;
632 struct virtio_pci_device *vp_dev = to_vp_device(vdev); 638 struct virtio_pci_device *vp_dev = to_vp_device(vdev);
633 struct virtio_pci_vq_info *info = vq->priv; 639 struct virtio_pci_vq_info *info = vp_dev->vqs[vq->index];
634 struct cpumask *mask; 640 struct cpumask *mask;
635 unsigned int irq; 641 unsigned int irq;
636 642