All of lore.kernel.org
 help / color / mirror / Atom feed
From: Izik Eidus <izike@qumranet.com>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] allow setting static devfn values for pci devices from the command line
Date: Mon, 19 Nov 2007 18:53:12 +0200	[thread overview]
Message-ID: <4741BF78.1040502@qumranet.com> (raw)
In-Reply-To: <4741B0FA.4070603@qumranet.com>

[-- Attachment #1: Type: text/plain, Size: 1146 bytes --]

Izik Eidus wrote:
> 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
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.

[-- Attachment #2: 0003-qemu-allow-setting-static-devfn-for-pci-devices-fro.patch --]
[-- Type: text/x-patch, Size: 7958 bytes --]

>From 6570e2859a43a1bc5178dc2130b1e91672fec6ae Mon Sep 17 00:00:00 2001
From: Izik Eidus <izike@qumranet.com>
Date: Mon, 19 Nov 2007 18:49:48 +0200
Subject: [PATCH] qemu: allow setting static devfn for pci devices from the command line

Signed-off-by: Izik Eidus <izike@qumranet.com>
---
 hw/pci.c |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 vl.c     |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 139 insertions(+), 5 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 0b5e7bf..3914704 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -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;
diff --git a/vl.c b/vl.c
index 8b2b5bd..7ae7275 100644
--- a/vl.c
+++ b/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"
@@ -871,6 +872,64 @@ static void rtc_stop_timer(struct qemu_alarm_timer *t);
 
 #endif /* _WIN32 */
 
+static void set_static_devfn(const char *optarg)
+{
+    int i;
+
+    if (*optarg == '?') {
+        printf("usage: -static-devfn dev_name=static_devfn_num\n"
+               "list of device names:\n"
+               "rtl8139 - realteak8139 network device\n"
+               "ne2000 - ne2000 network device\n"
+               "openpic\n"
+               "pcnet\n"
+               "i440fx\n"
+               "piix\n"
+               "vga - vga video card device\n"
+               "qemuware_svga - vmware svga video card device\n"
+               "piix3\n"
+               "piix4\n"
+               "macio\n"
+               "pci_brgd - pci bridge\n"
+               "cmd646_ide - ide device\n"
+               "advanced_pci_bus - acpi device\n"
+               "piix3_ide - ide device\n"
+               "prep_host_bridge_-motorola_raven\n"
+               "uni-north_main\n"
+               "uni-north_bridge\n"
+               "uni-north_agp\n"
+               "uni-north_internal\n"
+               "ochi_usb\n"
+               "usb_uchi\n"
+               "piix4_ide - ide device\n"
+               "lsi53c895a_scsi_hba\n"
+               "realview_eb_pci_controller\n"
+               "versatile/pb_pci_controller\n"
+               "cirrus_vga - cirrus vga video card device\n"
+               "es1370\n"
+               "grackle_host_bridge\n"
+               "gt64120_pci_bus\n"
+               "std-vga - standart vga video card device\n");
+               exit(0);
+        } else {
+            extern int static_devfns_index;
+            extern char static_devfns[PCI_DEVICES_MAX][64];
+            
+            if (static_devfns_index >= PCI_DEVICES_MAX) {
+                fprintf(stderr, "Too many static-devfns registred\n");
+                exit(1);
+            }
+            pstrcpy(static_devfns[static_devfns_index],
+                    sizeof(static_devfns[static_devfns_index]),
+                    optarg);
+            for (i = 0; static_devfns[static_devfns_index][i] &&
+                 i < sizeof(static_devfns[0]); i++)
+                if (static_devfns[static_devfns_index][i] == '_')
+                    static_devfns[static_devfns_index][i] = ' ';
+            static_devfns_index++;
+        }
+}
+
 static struct qemu_alarm_timer alarm_timers[] = {
 #ifndef _WIN32
 #ifdef __linux__
@@ -7076,6 +7135,8 @@ 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-devfn   set a static devfn for device\n"
+           "                use -static-devfn ? to get help\n"
 #if defined(TARGET_PPC) || defined(TARGET_SPARC)
            "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n"
 #endif
@@ -7243,6 +7304,7 @@ enum {
     QEMU_OPTION_win2k_hack,
     QEMU_OPTION_usb,
     QEMU_OPTION_usbdevice,
+    QEMU_OPTION_static_devfn,
     QEMU_OPTION_smp,
     QEMU_OPTION_vnc,
     QEMU_OPTION_no_acpi,
@@ -7339,6 +7401,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-devfn", HAS_ARG, QEMU_OPTION_static_devfn },
     { "smp", HAS_ARG, QEMU_OPTION_smp },
     { "vnc", HAS_ARG, QEMU_OPTION_vnc },
 
@@ -8111,6 +8174,9 @@ int main(int argc, char **argv)
                         optarg);
                 usb_devices_index++;
                 break;
+            case QEMU_OPTION_static_devfn:
+                set_static_devfn(optarg);
+                break;
             case QEMU_OPTION_smp:
                 smp_cpus = atoi(optarg);
                 if (smp_cpus < 1 || smp_cpus > MAX_CPUS) {
-- 
1.5.3.4


  reply	other threads:[~2007-11-19 17:04 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-19 15:51 [Qemu-devel] [PATCH] allow setting static devfn values for pci devices from the command line Izik Eidus
2007-11-19 16:53 ` Izik Eidus [this message]
2007-11-19 18:36   ` Jocelyn Mayer
2007-11-20  8:23     ` Izik Eidus

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4741BF78.1040502@qumranet.com \
    --to=izike@qumranet.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.