All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2] Make nic option rom loading less painful.
@ 2009-06-17 13:05 Glauber Costa
  0 siblings, 0 replies; only message in thread
From: Glauber Costa @ 2009-06-17 13:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori

The code how it is today, is totally painful to read and keep.
To begin with, the code is duplicated with the option rom loading
code that linux_boot and vga are already using.

This patch introduces a "bootable" state in NICInfo structure,
that we can use to keep track of whether or not a given nic should
be bootable, avoiding the introduction of yet another global state.

With that in hands, we move the code in vl.c to hw/pc.c, and use
the already existing infra structure to load those option roms.

Error checking code suggested by Mark McLoughlin

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 hw/pc.c |   19 +++++++++++++++++--
 net.c   |   20 ++++++++++++++++++++
 net.h   |    2 ++
 vl.c    |   39 ++++-----------------------------------
 4 files changed, 43 insertions(+), 37 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 0934778..ebf0aa5 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -977,8 +977,23 @@ static void pc_init1(ram_addr_t ram_size,
     }
 
     for (i = 0; i < nb_option_roms; i++) {
-        oprom_area_size += load_option_rom(option_rom[i],
-                                           0xc0000 + oprom_area_size, 0xe0000);
+        oprom_area_size += load_option_rom(option_rom[i], 0xc0000 + oprom_area_size,
+                                           0xe0000);
+    }
+
+    for (i = 0; i < nb_nics; i++) {
+        char nic_oprom[1024];
+        const char *model = nd_table[i].model;
+
+        if (!nd_table[i].bootable)
+            continue;
+
+        if (model == NULL)
+            model = "ne2k_pci";
+        snprintf(nic_oprom, sizeof(nic_oprom), "pxe-%s.bin", model);
+
+        oprom_area_size += load_option_rom(nic_oprom, 0xc0000 + oprom_area_size,
+                                           0xe0000);
     }
 
     /* map all the bios at the top of memory */
diff --git a/net.c b/net.c
index 2d24a7c..6324f22 100644
--- a/net.c
+++ b/net.c
@@ -2209,6 +2209,26 @@ int net_client_parse(const char *str)
     return net_client_init(device, p);
 }
 
+void net_set_boot_mask(int net_boot_mask)
+{
+    int i;
+
+    /* Only the first four NICs may be bootable */
+    net_boot_mask = net_boot_mask & 0xF;
+
+    for (i = 0; i < nb_nics; i++) {
+        if (net_boot_mask & (1 << i)) {
+            nd_table[i].bootable = 1;
+            net_boot_mask &= ~(1 << i);
+        }
+    }
+
+    if (net_boot_mask) {
+        fprintf(stderr, "Cannot boot from non-existent NIC\n");
+        exit(1);
+    }
+}
+
 void do_info_network(Monitor *mon)
 {
     VLANState *vlan;
diff --git a/net.h b/net.h
index feee021..22f5d8b 100644
--- a/net.h
+++ b/net.h
@@ -81,6 +81,7 @@ struct NICInfo {
     VLANState *vlan;
     void *private;
     int used;
+    int bootable;
 };
 
 extern int nb_nics;
@@ -116,6 +117,7 @@ void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2
 void net_cleanup(void);
 int slirp_is_inited(void);
 void net_client_check(void);
+void net_set_boot_mask(int boot_mask);
 void net_host_device_add(Monitor *mon, const char *device, const char *opts);
 void net_host_device_remove(Monitor *mon, int vlan_id, const char *device);
 
diff --git a/vl.c b/vl.c
index fcf8532..4a2e206 100644
--- a/vl.c
+++ b/vl.c
@@ -5781,7 +5781,6 @@ int main(int argc, char **argv, char **envp)
         exit(1);
     }
     linux_boot = (kernel_filename != NULL);
-    net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
 
     if (!linux_boot && *kernel_cmdline != '\0') {
         fprintf(stderr, "-append only allowed with -kernel option\n");
@@ -5829,41 +5828,11 @@ int main(int argc, char **argv, char **envp)
         if (net_client_parse(net_clients[i]) < 0)
             exit(1);
     }
-    net_client_check();
 
-#ifdef TARGET_I386
-    /* XXX: this should be moved in the PC machine instantiation code */
-    if (net_boot != 0) {
-        int netroms = 0;
-	for (i = 0; i < nb_nics && i < 4; i++) {
-	    const char *model = nd_table[i].model;
-	    char buf[1024];
-            char *filename;
-            if (net_boot & (1 << i)) {
-                if (model == NULL)
-                    model = "ne2k_pci";
-                snprintf(buf, sizeof(buf), "pxe-%s.bin", model);
-                filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, buf);
-                if (filename && get_image_size(filename) > 0) {
-                    if (nb_option_roms >= MAX_OPTION_ROMS) {
-                        fprintf(stderr, "Too many option ROMs\n");
-                        exit(1);
-                    }
-                    option_rom[nb_option_roms] = qemu_strdup(buf);
-                    nb_option_roms++;
-                    netroms++;
-                }
-                if (filename) {
-                    qemu_free(filename);
-                }
-            }
-	}
-	if (netroms == 0) {
-	    fprintf(stderr, "No valid PXE rom found for network device\n");
-	    exit(1);
-	}
-    }
-#endif
+    net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
+    net_set_boot_mask(net_boot);
+
+    net_client_check();
 
     /* init the bluetooth world */
     for (i = 0; i < nb_bt_opts; i++)
-- 
1.6.2.2

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2009-06-17 13:05 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-17 13:05 [Qemu-devel] [PATCH v2] Make nic option rom loading less painful Glauber Costa

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.