Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 340e01248478ba8b78a6d4d1809b1eff > files > 675

kvm-83-270.el5_11.src.rpm

From 7d8aec11edd78c04c1b316b6b833a40b0457e986 Mon Sep 17 00:00:00 2001
From: Sheng Yang <sheng@linux.intel.com>
Date: Thu, 21 May 2009 17:08:42 -0700
Subject: [PATCH 04/25] kvm: qemu: Figure out device capability

Try to figure out device capability in update_dev_cap(). Now we are only care
about MSI capability.

The function pci_find_cap_offset original function wrote by Allen for Xen.
Notice the function need root privilege to work. This depends on libpci to work.

[avi: drop #include <pci/pci.h> in device-assignment.h
      to avoid breakage on non-device-assignment-capable builds]

Signed-off-by: Allen Kay <allen.m.kay@intel.com>
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
(cherry picked from commit f976fbbadeb281aa7e1d9002ebcdce36d6e92621)
Signed-off-by: Chris Wright <chrisw@redhat.com>
Bugzilla: 498085
Message-Id: <1242950943-30180-5-git-send-email-chrisw@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
RH-Upstream-status: applied
Acked-by: Juan Quintela <quintela@redhat.com>
Acked-by: Marcelo Tosatti <mtosatti@redhat.com>
Acked-by: Don Dutile <ddutile@redhat.com>
---
 qemu/hw/device-assignment.c |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/qemu/hw/device-assignment.c b/qemu/hw/device-assignment.c
index 0634203..a807c5b 100644
--- a/qemu/hw/device-assignment.c
+++ b/qemu/hw/device-assignment.c
@@ -27,6 +27,7 @@
  */
 #include <stdio.h>
 #include <sys/io.h>
+#include <pci/pci.h>
 #include "qemu-kvm.h"
 #include "hw.h"
 #include "pc.h"
@@ -219,6 +220,35 @@ static void assigned_dev_ioport_map(PCIDevice *pci_dev, int region_num,
                           (r_dev->v_addrs + region_num));
 }
 
+static uint8_t pci_find_cap_offset(struct pci_dev *pci_dev, uint8_t cap)
+{
+    int id;
+    int max_cap = 48;
+    int pos = PCI_CAPABILITY_LIST;
+    int status;
+
+    status = pci_read_byte(pci_dev, PCI_STATUS);
+    if ((status & PCI_STATUS_CAP_LIST) == 0)
+        return 0;
+
+    while (max_cap--) {
+        pos = pci_read_byte(pci_dev, pos);
+        if (pos < 0x40)
+            break;
+
+        pos &= ~3;
+        id = pci_read_byte(pci_dev, pos + PCI_CAP_LIST_ID);
+
+        if (id == 0xff)
+            break;
+        if (id == cap)
+            return pos;
+
+        pos += PCI_CAP_LIST_NEXT;
+    }
+    return 0;
+}
+
 static void assigned_dev_pci_write_config(PCIDevice *d, uint32_t address,
                                           uint32_t val, int len)
 {
-- 
1.6.3.rc4.29.g8146