Skip to contentSkip to conversation

allow setting static devfn values for pci devices from the command line

PATCH In review Izik Eidus 2 participants 4 messages Nov 19, 2007 – Nov 20, 2007

lore
Share & tools
lore

Izik Eidus

author
#0 lore raw

PATCH 1/1 allow setting static devfn values for pci devices from the command line

hi,
this patch make it possible to define from the command line a static devfn value for each pci device.
it was wrote for addressing a problem that right now qemu devices get their devfn in random way (almost random)
the problem with this is that with adding and removing devices some devfn values can be changed for each device.
this make (at least) windows unable to understand what happned to your device and mark it in yellow color. (and will want you to reinstall it)

in this patch i simply use the device name that was registred with the pci device registration function.
in case you have few devices from the same type (same name), it will simply increase each by one so in this case all you have to do is give long enough offset for the devfns from each other.

thanks

Quoted 1 line

From 3b26c9a10ddc01bf68c8d8e488559e3a082fa36b Mon Sep 17 00:00:00 2001

From: Izik Eidus <[email protected]>
Date: Mon, 19 Nov 2007 17:41:49 +0200
Subject: [PATCH] qemu: allow setting static devfn for pci devices from the command line

---
 hw/pci.c |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 vl.c     |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 139 insertions(+), 5 deletions(-)
hw/pci.c +73 -5
index 0b5e7bf..d12184c 100644
@@ -52,6 +52,9 @@ target_phys_addr_t pci_mem_base;
 static int pci_irq_index;
 static PCIBus *first_bus;
 
+char static_devfns[PCI_DEVICES_MAX][128];
+int static_devfns_index = 0;
+
 PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                          qemu_irq *pic, int devfn_min, int nirq)
 {
@@ -98,6 +101,67 @@ int pci_device_load(PCIDevice *s, QEMUFile *f)
     return 0;
 }
 
+int pci_read_static_devfn(PCIBus *bus, const char *name)
+{
+    int i;
+    int y;
+    int count;
+
+    for (i = 0; i < static_devfns_index; i++) {
+        count = 0;
+        for (y = 0; y < sizeof(static_devfns[0]) && name[y]; y++) {
+            if (tolower(static_devfns[i][y]) != tolower(name[y]))
+                continue;
+            count++;
+        }
+        /*if count is y we found devfn value for this device name */
+        if (count == y && y < sizeof(static_devfns[0]) &&
+            static_devfns[i][y] == '=') {
+            int devfn;
+            char *value_buffer;
+
+            static_devfns[i][sizeof(static_devfns[0]) - 1] = '\0';
+            value_buffer = strstr(static_devfns[i], "=");
+            if (!value_buffer)
+                return -1;
+            value_buffer++;
+            devfn = atoi(value_buffer);
+            if (devfn < 0)
+                return -1;
+            /*
+             * check if the devfn is already registered in case this pci device
+             * is registering now not for the first time.
+             * in this case we increase the value of the devfn by one untill
+             * we find a free devfn
+             * note: you should provide devices we big enougth spaces beteween
+             * them if you want to register the same devices more than once
+             */
+            for (; devfn < 256; devfn++)
+                if (!bus->devices[devfn])
+                    return devfn;
+            return -1;
+        }
+    }
+    return -1;
+}
+
+int pci_is_static_devfn(int devfn)
+{
+    int i;
+    char *value_buffer;
+
+    for (i = 0; i < static_devfns_index; i++) {
+        static_devfns[i][sizeof(static_devfns[0]) - 1] = '\0';
+        value_buffer = strstr(static_devfns[i], "=");
+        value_buffer++;
+        if (!value_buffer)
+            continue;
+        if (devfn == atoi(value_buffer))
+            return 1;
+    }
+    return 0;
+}
+
 /* -1 for devfn means auto assign */
 PCIDevice *pci_register_device(PCIBus *bus, const char *name,
                                int instance_size, int devfn,
@@ -110,13 +174,17 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
         return NULL;
 
     if (devfn < 0) {
-        for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
-            if (!bus->devices[devfn])
-                goto found;
+        devfn = pci_read_static_devfn(bus, name);
+        if (devfn < 0) {
+            for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
+                if (!bus->devices[devfn] && !pci_is_static_devfn(devfn))
+                    goto found;
+            }
+            return NULL;
+        found: ;
         }
-        return NULL;
-    found: ;
     }
+
     pci_dev = qemu_mallocz(instance_size);
     if (!pci_dev)
         return NULL;
vl.c +66 -0

102 lines not on this page · raw message

Signature · 1 line
1.5.3.4
author
#1 lore raw
Quoted 10 lines · Izik Eidus

hi,
this patch make it possible to define from the command line a static devfn value for each pci device.
it was wrote for addressing a problem that right now qemu devices get their devfn in random way (almost random)
the problem with this is that with adding and removing devices some devfn values can be changed for each device.
this make (at least) windows unable to understand what happned to your device and mark it in yellow color. (and will want you to reinstall it)

Quoted 6 lines

in this patch i simply use the device name that was registred with the pci device registration function.
in case you have few devices from the same type (same name), it will simply increase each by one so in this case all you have to do is give long enough offset for the devfns from each other.

thanks

ok here is a fix to two issues that i noticed:
1.in one place i declared static_devfns[MAX_PCI_DEVICS][64] and in other place: static_devfns[MAX_PCI_DEVICS][128]

2.in one place i did a calculation on a pointer line before i checked if it is vaild pointer...

anyway here it is again and fixed.

Quoted 1 line

From 6570e2859a43a1bc5178dc2130b1e91672fec6ae Mon Sep 17 00:00:00 2001

From: Izik Eidus <[email protected]>
Date: Mon, 19 Nov 2007 18:49:48 +0200
Subject: [PATCH] qemu: allow setting static devfn for pci devices from the command line

---
 hw/pci.c |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 vl.c     |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 139 insertions(+), 5 deletions(-)
hw/pci.c +73 -5
index 0b5e7bf..3914704 100644
@@ -52,6 +52,9 @@ target_phys_addr_t pci_mem_base;
 static int pci_irq_index;
 static PCIBus *first_bus;
 
+char static_devfns[PCI_DEVICES_MAX][64];
+int static_devfns_index = 0;
+
 PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                          qemu_irq *pic, int devfn_min, int nirq)
 {
@@ -98,6 +101,67 @@ int pci_device_load(PCIDevice *s, QEMUFile *f)
     return 0;
 }
 
+int pci_read_static_devfn(PCIBus *bus, const char *name)
+{
+    int i;
+    int y;
+    int count;
+
+    for (i = 0; i < static_devfns_index; i++) {
+        count = 0;
+        for (y = 0; y < sizeof(static_devfns[0]) && name[y]; y++) {
+            if (tolower(static_devfns[i][y]) != tolower(name[y]))
+                continue;
+            count++;
+        }
+        /*if count is y we found devfn value for this device name */
+        if (count == y && y < sizeof(static_devfns[0]) &&
+            static_devfns[i][y] == '=') {
+            int devfn;
+            char *value_buffer;
+
+            static_devfns[i][sizeof(static_devfns[0]) - 1] = '\0';
+            value_buffer = strstr(static_devfns[i], "=");
+            if (!value_buffer)
+                return -1;
+            value_buffer++;
+            devfn = atoi(value_buffer);
+            if (devfn < 0)
+                return -1;
+            /*
+             * check if the devfn is already registered in case this pci device
+             * is registering now not for the first time.
+             * in this case we increase the value of the devfn by one untill
+             * we find a free devfn
+             * note: you should provide devices we big enougth spaces beteween
+             * them if you want to register the same devices more than once
+             */
+            for (; devfn < 256; devfn++)
+                if (!bus->devices[devfn])
+                    return devfn;
+            return -1;
+        }
+    }
+    return -1;
+}
+
+int pci_is_static_devfn(int devfn)
+{
+    int i;
+    char *value_buffer;
+
+    for (i = 0; i < static_devfns_index; i++) {
+        static_devfns[i][sizeof(static_devfns[0]) - 1] = '\0';
+        value_buffer = strstr(static_devfns[i], "=");
+        if (!value_buffer)
+            continue;
+        value_buffer++;
+        if (devfn == atoi(value_buffer))
+            return 1;
+    }
+    return 0;
+}
+
 /* -1 for devfn means auto assign */
 PCIDevice *pci_register_device(PCIBus *bus, const char *name,
                                int instance_size, int devfn,
@@ -110,13 +174,17 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
         return NULL;
 
     if (devfn < 0) {
-        for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
-            if (!bus->devices[devfn])
-                goto found;
+        devfn = pci_read_static_devfn(bus, name);
+        if (devfn < 0) {
+            for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
+                if (!bus->devices[devfn] && !pci_is_static_devfn(devfn))
+                    goto found;
+            }
+            return NULL;
+        found: ;
         }
-        return NULL;
-    found: ;
     }
+
     pci_dev = qemu_mallocz(instance_size);
     if (!pci_dev)
         return NULL;
vl.c +66 -0

102 lines not on this page · raw message

Signature · 1 line
1.5.3.4
#2 lore raw
Quoted 24 lines · Izik Eidus
Quoted 22 lines · Izik Eidus

hi,
this patch make it possible to define from the command line a static devfn value for each pci
device.
it was wrote for addressing a problem that right now qemu devices get their devfn in random way
(almost random)
the problem with this is that with adding and removing devices some devfn values can be changed
for each device.
this make (at least) windows unable to understand what happned to your device and mark it
in yellow color. (and will want you to reinstall it)

in this patch i simply use the device name that was registred with the pci device registration
function.
in case you have few devices from the same type (same name), it will simply increase each by one
so in this case all you have to do is give long enough offset for the devfns from each other.

Quoted 1 line

thanks

Quoted 8 lines

ok here is a fix to two issues that i noticed:
1.in one place i declared static_devfns[MAX_PCI_DEVICS][64] and in other
place: static_devfns[MAX_PCI_DEVICS][128]

2.in one place i did a calculation on a pointer line before i checked if it is vaild pointer...

anyway here it is again and fixed.

It seems that you cannot impose the PCI device numbers mapping, which is likely to be architecture dependant. What you could however change is the PCI bus & slot the device is inserted into, the same way you can choose the PCI slot you put a PCI card into on a real machine. The architecture could then determine what is the corresponding PCI device number, given this PCI bus & slot numbers.
For other PCI devices, like PCI bridges or other internal devices, the PCI slots / devfn are fixed by the architecture. You cannot change them in any way, then it seems pointless to have an option that would change the behavior for any of those devices.
The last problem I see is that it seems very ugly to hardcode the device names the way you did in vl.c. This is even false in most cases, as most of those devices are only available for a few machines and are not tunable at all (for example macio or uninorth are only available in some Apple Mac machines, not even all).

Signature · 1 line
Jocelyn Mayer <[email protected]>
author
#3 lore raw
Quoted 29 lines · Jocelyn Mayer
Quoted 17 lines · Izik Eidus
Quoted 15 lines · Izik Eidus

hi,
this patch make it possible to define from the command line a static devfn value for each pci device.
it was wrote for addressing a problem that right now qemu devices get their devfn in random way (almost random)
the problem with this is that with adding and removing devices some devfn values can be changed for each device.
this make (at least) windows unable to understand what happned to your device and mark it in yellow color. (and will want you to reinstall it)

in this patch i simply use the device name that was registred with the pci device registration function.
in case you have few devices from the same type (same name), it will simply increase each by one so in this case all you have to do is give long enough offset for the devfns from each other.

Quoted 9 lines
Quoted 2 lines

thanks

ok here is a fix to two issues that i noticed:
1.in one place i declared static_devfns[MAX_PCI_DEVICS][64] and in other place: static_devfns[MAX_PCI_DEVICS][128]

2.in one place i did a calculation on a pointer line before i checked if it is vaild pointer...

anyway here it is again and fixed.

Quoted 6 lines

It seems that you cannot impose the PCI device numbers mapping, which is likely to be architecture dependant. What you could however change is the PCI bus & slot the device is inserted into, the same way you can choose the PCI slot you put a PCI card into on a real machine. The architecture could then determine what is the corresponding PCI device number, given this PCI bus & slot numbers.

i will check this.

Quoted 10 lines

For other PCI devices, like PCI bridges or other internal devices, the PCI slots / devfn are fixed by the architecture. You cannot change them in any way, then it seems pointless to have an option that would change the behavior for any of those devices.
The last problem I see is that it seems very ugly to hardcode the device names the way you did in vl.c. This is even false in most cases, as most of those devices are only available for a few machines and are not tunable at all (for example macio or uninorth are only available in some Apple Mac machines, not even all).

so how will i inform the user with the devices name?