diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 2c9f48076..7004aaf23 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -714,12 +714,6 @@ module = {
common = commands/probe.c;
};
-module = {
- name = pxecmd;
- i386_pc = commands/i386/pc/pxecmd.c;
- enable = i386_pc;
-};
-
module = {
name = read;
common = commands/read.c;
diff --git a/grub-core/commands/i386/pc/pxecmd.c b/grub-core/commands/i386/pc/pxecmd.c
deleted file mode 100644
index dffa15a3a..000000000
--- a/grub-core/commands/i386/pc/pxecmd.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* pxe.c - command to control the pxe driver */
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2008,2009 Free Software Foundation, Inc.
- *
- * GRUB is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GRUB is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GRUB. If not, see .
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-GRUB_MOD_LICENSE ("GPLv3+");
-
-static grub_err_t
-grub_cmd_pxe_unload (grub_command_t cmd __attribute__ ((unused)),
- int argc __attribute__ ((unused)),
- char **args __attribute__ ((unused)))
-{
- if (! grub_pxe_pxenv)
- return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no pxe environment");
-
- grub_pxe_unload ();
-
- return 0;
-}
-
-static grub_command_t cmd;
-
-GRUB_MOD_INIT(pxecmd)
-{
- cmd = grub_register_command ("pxe_unload", grub_cmd_pxe_unload,
- 0,
- N_("Unload PXE environment."));
-}
-
-GRUB_MOD_FINI(pxecmd)
-{
- grub_unregister_command (cmd);
-}
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
index 1328cd57c..4b2ffc038 100644
--- a/grub-core/net/drivers/efi/efinet.c
+++ b/grub-core/net/drivers/efi/efinet.c
@@ -184,23 +184,18 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
}
}
-
GRUB_MOD_INIT(efinet)
{
grub_efinet_findcards ();
grub_efi_net_config = grub_efi_net_config_real;
}
-GRUB_MOD_FINI(ofnet)
+GRUB_MOD_FINI(efinet)
{
- struct grub_net_card *card;
- grub_efi_net_config = 0;
- FOR_NET_CARDS (card)
- if (card->driver && !grub_strcmp (card->driver->name, "efinet"))
- {
- card->driver->fini (card);
- card->driver = NULL;
- }
- grub_net_card_driver_unregister (&efidriver);
+ struct grub_net_card *card, *next;
+
+ FOR_NET_CARDS_SAFE (card, next)
+ if (card->driver && grub_strcmp (card->driver->name, "efinet") == 0)
+ grub_net_card_unregister (card);
}
diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c
index 51f4023a6..81607eb57 100644
--- a/grub-core/net/drivers/i386/pc/pxe.c
+++ b/grub-core/net/drivers/i386/pc/pxe.c
@@ -22,8 +22,8 @@
#include
#include
#include
-#include
#include
+#include
#include
#include
@@ -273,19 +273,36 @@ struct grub_net_card grub_pxe_card =
.name = "pxe"
};
-void
-grub_pxe_unload (void)
+static grub_err_t
+grub_pxe_fini_hw (int noreturn __attribute__ ((unused)))
{
if (pxe_rm_entry)
- {
- grub_pxe_call (GRUB_PXENV_UNDI_CLOSE,
- (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR,
- pxe_rm_entry);
- grub_net_card_unregister (&grub_pxe_card);
- grub_pxe_pxenv = 0;
- }
+ grub_pxe_call (GRUB_PXENV_UNDI_CLOSE,
+ (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR,
+ pxe_rm_entry);
+
+ return GRUB_ERR_NONE;
}
+static grub_err_t
+grub_pxe_restore_hw (void)
+{
+ struct grub_pxe_undi_open *ou;
+ ou = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+ grub_memset (ou, 0, sizeof (*ou));
+ ou->pkt_filter = 4;
+ grub_pxe_call (GRUB_PXENV_UNDI_OPEN, ou, pxe_rm_entry);
+
+ if (ou->status)
+ {
+ grub_net_card_unregister (&grub_pxe_card);
+ return grub_error (GRUB_ERR_IO, "can't open UNDI");
+ }
+ return GRUB_ERR_NONE;
+}
+
+static void *fini_hnd;
+
static void
grub_pc_net_config_real (char **device, char **path)
{
@@ -303,6 +320,7 @@ grub_pc_net_config_real (char **device, char **path)
grub_net_configure_by_dhcp_ack ("pxe", &grub_pxe_card, 0,
bp, GRUB_PXE_BOOTP_SIZE,
1, device, path);
+
}
GRUB_MOD_INIT(pxe)
@@ -347,10 +365,20 @@ GRUB_MOD_INIT(pxe)
grub_net_card_register (&grub_pxe_card);
grub_pc_net_config = grub_pc_net_config_real;
+ fini_hnd = grub_loader_register_preboot_hook (grub_pxe_fini_hw,
+ grub_pxe_restore_hw,
+ GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK);
}
GRUB_MOD_FINI(pxe)
{
+ struct grub_net_card *card, *next;
+
grub_pc_net_config = 0;
- grub_pxe_unload ();
+ grub_pxe_fini_hw (0);
+ grub_net_card_unregister (&grub_pxe_card);
+ FOR_NET_CARDS_SAFE (card, next)
+ if (card->driver && grub_strcmp (card->driver->name, "pxe") == 0)
+ grub_net_card_unregister (card);
+ grub_loader_unregister_preboot_hook (fini_hnd);
}
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
index 595379a99..96bbd1712 100644
--- a/grub-core/net/net.c
+++ b/grub-core/net/net.c
@@ -52,7 +52,6 @@ struct grub_net_route
struct grub_net_route *grub_net_routes = NULL;
struct grub_net_network_level_interface *grub_net_network_level_interfaces = NULL;
struct grub_net_card *grub_net_cards = NULL;
-struct grub_net_card_driver *grub_net_card_drivers = NULL;
struct grub_net_network_level_protocol *grub_net_network_level_protocols = NULL;
static struct grub_fs grub_net_fs;
@@ -1321,16 +1320,6 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)),
return err;
}
-static void
-grub_grubnet_fini_real (void)
-{
- struct grub_net_card *card;
-
- FOR_NET_CARDS (card)
- if (card->driver)
- card->driver->fini (card);
-}
-
static struct grub_fs grub_net_fs =
{
.name = "netfs",
@@ -1378,7 +1367,6 @@ GRUB_MOD_INIT(net)
grub_fs_register (&grub_net_fs);
grub_net_open = grub_net_open_real;
- grub_grubnet_fini = grub_grubnet_fini_real;
}
GRUB_MOD_FINI(net)
@@ -1393,5 +1381,4 @@ GRUB_MOD_FINI(net)
grub_unregister_command (cmd_getdhcp);
grub_fs_unregister (&grub_net_fs);
grub_net_open = NULL;
- grub_grubnet_fini = NULL;
}
diff --git a/include/grub/net.h b/include/grub/net.h
index 0656787a6..e9a3793db 100644
--- a/include/grub/net.h
+++ b/include/grub/net.h
@@ -60,32 +60,12 @@ struct grub_net_card_driver
{
struct grub_net_card_driver *next;
char *name;
- grub_err_t (*init) (struct grub_net_card *dev);
- grub_err_t (*fini) (struct grub_net_card *dev);
grub_err_t (*send) (const struct grub_net_card *dev,
struct grub_net_buff *buf);
grub_ssize_t (*recv) (const struct grub_net_card *dev,
struct grub_net_buff *buf);
};
-extern struct grub_net_card_driver *grub_net_card_drivers;
-
-static inline void
-grub_net_card_driver_register (struct grub_net_card_driver *driver)
-{
- grub_list_push (GRUB_AS_LIST_P (&grub_net_card_drivers),
- GRUB_AS_LIST (driver));
-}
-
-static inline void
-grub_net_card_driver_unregister (struct grub_net_card_driver *driver)
-{
- grub_list_remove (GRUB_AS_LIST_P (&grub_net_card_drivers),
- GRUB_AS_LIST (driver));
-}
-
-#define FOR_NET_CARD_DRIVERS(var) for (var = grub_net_card_drivers; var; var = var->next)
-
typedef struct grub_net_packet
{
struct grub_net_packet *next;
@@ -250,7 +230,6 @@ typedef struct grub_net
} *grub_net_t;
extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name);
-extern void (*EXPORT_VAR (grub_grubnet_fini)) (void);
struct grub_net_network_level_interface
{
@@ -350,6 +329,8 @@ grub_net_card_unregister (struct grub_net_card *card)
}
#define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next)
+#define FOR_NET_CARDS_SAFE(var, next) for (var = grub_net_cards, next = var->next; var; var = next, next = var->next)
+
struct grub_net_session *
grub_net_open_tcp (char *address, grub_uint16_t port);