aboutsummaryrefslogtreecommitdiffstats
path: root/extras
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-10-14 08:31:07 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-10-14 08:31:07 +0100
commit2757a76076b2f13700249e3a79bcd89d0c491479 (patch)
tree77f6c08d0545e3171aef5502822190ac1da7d4bc /extras
parent49d46b98d65b702693e2300337de8349422866cb (diff)
downloadxen-2757a76076b2f13700249e3a79bcd89d0c491479.tar.gz
xen-2757a76076b2f13700249e3a79bcd89d0c491479.tar.bz2
xen-2757a76076b2f13700249e3a79bcd89d0c491479.zip
minios pcifront: translate physical into virtual addresses
Qemu understands physical pci addresses while pciback expects virtual pci addresses: this patch adds a translation function in pcifront to make the conversion. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Diffstat (limited to 'extras')
-rw-r--r--extras/mini-os/pcifront.c65
1 files changed, 63 insertions, 2 deletions
diff --git a/extras/mini-os/pcifront.c b/extras/mini-os/pcifront.c
index d8a5a946fc..afbe0fc9d7 100644
--- a/extras/mini-os/pcifront.c
+++ b/extras/mini-os/pcifront.c
@@ -191,10 +191,10 @@ void pcifront_scan(struct pcifront_dev *dev, void (*func)(unsigned int domain, u
n = xenbus_read_integer(path);
for (i = 0; i < n; i++) {
- snprintf(path, sizeof(path), "%s/vdev-%d", dev->backend, i);
+ snprintf(path, sizeof(path), "%s/dev-%d", dev->backend, i);
msg = xenbus_read(XBT_NIL, path, &s);
if (msg) {
- printk("Error %s when reading the PCI root name at %s\n", path);
+ printk("Error %s when reading the PCI root name at %s\n", msg, path);
continue;
}
@@ -260,6 +260,55 @@ close_pcifront:
free_pcifront(dev);
}
+int pcifront_physical_to_virtual (struct pcifront_dev *dev,
+ unsigned int *dom,
+ unsigned int *bus,
+ unsigned int *slot,
+ unsigned long *fun)
+{
+ char path[strlen(dev->backend) + 1 + 5 + 10 + 1];
+ int i, n;
+ char *s, *msg = NULL;
+ unsigned int dom1, bus1, slot1, fun1;
+
+ snprintf(path, sizeof(path), "%s/num_devs", dev->backend);
+ n = xenbus_read_integer(path);
+
+ for (i = 0; i < n; i++) {
+ snprintf(path, sizeof(path), "%s/dev-%d", dev->backend, i);
+ msg = xenbus_read(XBT_NIL, path, &s);
+ if (msg) {
+ printk("Error %s when reading the PCI root name at %s\n", msg, path);
+ continue;
+ }
+
+ if (sscanf(s, "%x:%x:%x.%x", &dom1, &bus1, &slot1, &fun1) != 4) {
+ printk("\"%s\" does not look like a PCI device address\n", s);
+ free(s);
+ continue;
+ }
+ free(s);
+
+ if (dom1 == *dom && bus1 == *bus && slot1 == *slot && fun1 == *fun) {
+ snprintf(path, sizeof(path), "%s/vdev-%d", dev->backend, i);
+ msg = xenbus_read(XBT_NIL, path, &s);
+ if (msg) {
+ printk("Error %s when reading the PCI root name at %s\n", msg, path);
+ continue;
+ }
+
+ if (sscanf(s, "%x:%x:%x.%x", dom, bus, slot, fun) != 4) {
+ printk("\"%s\" does not look like a PCI device address\n", s);
+ free(s);
+ continue;
+ }
+ free(s);
+
+ return 0;
+ }
+ }
+ return -1;
+}
void pcifront_op(struct pcifront_dev *dev, struct xen_pci_op *op)
{
@@ -283,6 +332,8 @@ int pcifront_conf_read(struct pcifront_dev *dev,
{
struct xen_pci_op op;
+ if (pcifront_physical_to_virtual(dev, &dom, &bus, &slot, &fun) < 0)
+ return XEN_PCI_ERR_dev_not_found;
memset(&op, 0, sizeof(op));
op.cmd = XEN_PCI_OP_conf_read;
@@ -309,6 +360,8 @@ int pcifront_conf_write(struct pcifront_dev *dev,
{
struct xen_pci_op op;
+ if (pcifront_physical_to_virtual(dev, &dom, &bus, &slot, &fun) < 0)
+ return XEN_PCI_ERR_dev_not_found;
memset(&op, 0, sizeof(op));
op.cmd = XEN_PCI_OP_conf_write;
@@ -331,6 +384,8 @@ int pcifront_enable_msi(struct pcifront_dev *dev,
{
struct xen_pci_op op;
+ if (pcifront_physical_to_virtual(dev, &dom, &bus, &slot, &fun) < 0)
+ return XEN_PCI_ERR_dev_not_found;
memset(&op, 0, sizeof(op));
op.cmd = XEN_PCI_OP_enable_msi;
@@ -352,6 +407,8 @@ int pcifront_disable_msi(struct pcifront_dev *dev,
{
struct xen_pci_op op;
+ if (pcifront_physical_to_virtual(dev, &dom, &bus, &slot, &fun) < 0)
+ return XEN_PCI_ERR_dev_not_found;
memset(&op, 0, sizeof(op));
op.cmd = XEN_PCI_OP_disable_msi;
@@ -371,6 +428,8 @@ int pcifront_enable_msix(struct pcifront_dev *dev,
{
struct xen_pci_op op;
+ if (pcifront_physical_to_virtual(dev, &dom, &bus, &slot, &fun) < 0)
+ return XEN_PCI_ERR_dev_not_found;
if (n > SH_INFO_MAX_VEC)
return XEN_PCI_ERR_op_failed;
@@ -401,6 +460,8 @@ int pcifront_disable_msix(struct pcifront_dev *dev,
{
struct xen_pci_op op;
+ if (pcifront_physical_to_virtual(dev, &dom, &bus, &slot, &fun) < 0)
+ return XEN_PCI_ERR_dev_not_found;
memset(&op, 0, sizeof(op));
op.cmd = XEN_PCI_OP_disable_msix;