qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] allow setting static slot values for pci devices fr


From: Izik Eidus
Subject: [Qemu-devel] [PATCH] allow setting static slot values for pci devices from the command line
Date: Tue, 22 Jan 2008 14:30:57 +0200
User-agent: Thunderbird 2.0.0.9 (X11/20071115)

hi,
2 months ago i sent a patch that was called "static devfn" i described it as a patch that allow setting static value for the devfn due to a bad name that i gave it there was a confusion about this patch, what it really was doing is allowing setting static values
for the pci slot,
i cleaned this patch again and change some stuff in it to make it more clear and send it now again.

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

thanks

--
woof.

diff --git a/qemu/hw/pci.c b/qemu/hw/pci.c
index 545901c..9362ae7 100644
--- a/qemu/hw/pci.c
+++ b/qemu/hw/pci.c
@@ -85,6 +85,9 @@ static int  pcibus_load(QEMUFile *f, void *opaque, int 
version_id)
     return 0;
 }
 
+char static_slots[PCI_DEVICES_MAX][64];
+int static_slots_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)
 {
@@ -146,6 +149,67 @@ int pci_device_load(PCIDevice *s, QEMUFile *f)
     return 0;
 }
 
+int pci_read_static_slot(PCIBus *bus, const char *name)
+{
+    int i;
+    int y;
+    int count;
+
+    for (i = 0; i < static_slots_index; i++) {
+        count = 0;
+        for (y = 0; y < sizeof(static_slots[0]) && name[y]; y++) {
+            if (tolower(static_slots[i][y]) != tolower(name[y]))
+                continue;
+            count++;
+        }
+        /*if count is y we found slot value for this device name */
+        if (count == y && y < sizeof(static_slots[0]) &&
+            static_slots[i][y] == '=') {
+            int slot;
+            char *value_buffer;
+
+            static_slots[i][sizeof(static_slots[0]) - 1] = '\0';
+            value_buffer = strstr(static_slots[i], "=");
+            if (!value_buffer)
+                return -1;
+            value_buffer++;
+            slot = atoi(value_buffer);
+            if (slot < 0)
+                return -1;
+            /*
+             * check if the slot 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 slot by one untill
+             * we find a free slot
+             * note: you should provide devices we big enougth spaces beteween
+             * them if you want to register the same devices more than once
+             */
+            for (; slot < 32; slot++)
+                if (!bus->devices[slot * 8])
+                    return slot;
+            return -1;
+        }
+    }
+    return -1;
+}
+
+int pci_is_static_slot(int slot)
+{
+    int i;
+    char *value_buffer;
+
+    for (i = 0; i < static_slots_index; i++) {
+        static_slots[i][sizeof(static_slots[0]) - 1] = '\0';
+        value_buffer = strstr(static_slots[i], "=");
+        if (!value_buffer)
+            continue;
+        value_buffer++;
+        if (slot == 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,
@@ -158,13 +222,20 @@ 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;
-        }
-        return NULL;
-    found: ;
+        int slot;
+
+        slot = pci_read_static_slot(bus, name);
+        if (slot < 0) {
+            for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
+                if (!bus->devices[devfn] && !pci_is_static_slot(devfn / 8))
+                    goto found;
+            }
+            return NULL;
+        found: ;
+        } else
+            devfn = slot * 8;
     }
+
     pci_dev = qemu_mallocz(instance_size);
     if (!pci_dev)
         return NULL;
diff --git a/qemu/vl.c b/qemu/vl.c
index 756e13d..54ddb9e 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -29,6 +29,7 @@
 #include "hw/fdc.h"
 #include "hw/audiodev.h"
 #include "hw/isa.h"
+#include "hw/pci.h"
 #include "net.h"
 #include "console.h"
 #include "sysemu.h"
@@ -906,6 +907,26 @@ static void rtc_stop_timer(struct qemu_alarm_timer *t);
 
 #endif /* _WIN32 */
 
+static void set_static_slot(const char *optarg)
+{
+    int i;
+    extern int static_slots_index;
+    extern char static_slots[PCI_DEVICES_MAX][64];
+  
+    if (static_slots_index >= PCI_DEVICES_MAX) {
+        fprintf(stderr, "Too many static-slots registred\n");
+        exit(1);
+    }
+    pstrcpy(static_slots[static_slots_index],
+            sizeof(static_slots[static_slots_index]),
+            optarg);
+    for (i = 0; static_slots[static_slots_index][i] &&
+         i < sizeof(static_slots[0]); i++)
+    if (static_slots[static_slots_index][i] == '_')
+            static_slots[static_slots_index][i] = ' ';
+    static_slots_index++;
+}
+
 static struct qemu_alarm_timer alarm_timers[] = {
 #ifndef _WIN32
 #ifdef __linux__
@@ -7948,6 +7969,9 @@ static void help(int exitcode)
 #endif
            "-usb            enable the USB driver (will be the default soon)\n"
            "-usbdevice name add the host or guest USB device 'name'\n"
+           "-static-slot    set a static slot for device\n"
+           "                usage: -static-slot dev_name=static_slot_num\n"
+
 #if defined(TARGET_PPC) || defined(TARGET_SPARC)
            "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n"
 #endif
@@ -8126,6 +8150,7 @@ enum {
     QEMU_OPTION_win2k_hack,
     QEMU_OPTION_usb,
     QEMU_OPTION_usbdevice,
+    QEMU_OPTION_static_slot,
     QEMU_OPTION_smp,
     QEMU_OPTION_vnc,
     QEMU_OPTION_no_acpi,
@@ -8237,6 +8262,7 @@ const QEMUOption qemu_options[] = {
     { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
     { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
     { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
+    { "static-slot", HAS_ARG, QEMU_OPTION_static_slot },
     { "smp", HAS_ARG, QEMU_OPTION_smp },
     { "vnc", HAS_ARG, QEMU_OPTION_vnc },
 
@@ -9061,6 +9087,9 @@ int main(int argc, char **argv)
                         optarg);
                 usb_devices_index++;
                 break;
+            case QEMU_OPTION_static_slot:
+                set_static_slot(optarg);
+                break;
             case QEMU_OPTION_smp:
                 smp_cpus = atoi(optarg);
                 if (smp_cpus < 1 || smp_cpus > MAX_CPUS) {

reply via email to

[Prev in Thread] Current Thread [Next in Thread]