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);