qemu-devel.nongnu.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).