summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/arch/i386/drivers/net/undionly.c6
-rw-r--r--src/arch/i386/image/bzimage.c2
-rw-r--r--src/arch/i386/image/elfboot.c2
-rw-r--r--src/arch/i386/image/multiboot.c2
-rw-r--r--src/arch/i386/image/nbi.c2
-rw-r--r--src/arch/i386/interface/pcbios/int13.c8
-rw-r--r--src/arch/i386/interface/pxe/pxe_call.c2
-rw-r--r--src/arch/i386/interface/pxe/pxe_preboot.c2
-rw-r--r--src/arch/i386/interface/syslinux/comboot_call.c4
-rw-r--r--src/core/device.c7
-rw-r--r--src/core/main.c2
-rw-r--r--src/drivers/net/efi/snponly.c6
-rw-r--r--src/image/efi_image.c2
-rw-r--r--src/include/ipxe/device.h18
-rw-r--r--src/include/ipxe/init.h30
-rw-r--r--src/include/usr/autoboot.h2
-rw-r--r--src/usr/autoboot.c4
17 files changed, 64 insertions, 37 deletions
diff --git a/src/arch/i386/drivers/net/undionly.c b/src/arch/i386/drivers/net/undionly.c
index ab9c61fb..c38b574d 100644
--- a/src/arch/i386/drivers/net/undionly.c
+++ b/src/arch/i386/drivers/net/undionly.c
@@ -114,13 +114,13 @@ struct root_device undi_root_device __root_device = {
/**
* Prepare for exit
*
- * @v flags Shutdown flags
+ * @v booting System is shutting down for OS boot
*/
-static void undionly_shutdown ( int flags ) {
+static void undionly_shutdown ( int booting ) {
/* If we are shutting down to boot an OS, clear the "keep PXE
* stack" flag.
*/
- if ( flags & SHUTDOWN_BOOT )
+ if ( booting )
preloaded_undi.flags &= ~UNDI_FL_KEEP_ALL;
}
diff --git a/src/arch/i386/image/bzimage.c b/src/arch/i386/image/bzimage.c
index 900e34e1..45a1e862 100644
--- a/src/arch/i386/image/bzimage.c
+++ b/src/arch/i386/image/bzimage.c
@@ -477,7 +477,7 @@ static int bzimage_exec ( struct image *image ) {
bzimage_update_header ( image, &bzimg, bzimg.rm_kernel );
/* Prepare for exiting */
- shutdown ( SHUTDOWN_BOOT );
+ shutdown_boot();
DBGC ( image, "bzImage %p jumping to RM kernel at %04x:0000 "
"(stack %04x:%04zx)\n", image, ( bzimg.rm_kernel_seg + 0x20 ),
diff --git a/src/arch/i386/image/elfboot.c b/src/arch/i386/image/elfboot.c
index 7cb51bf9..331d3764 100644
--- a/src/arch/i386/image/elfboot.c
+++ b/src/arch/i386/image/elfboot.c
@@ -48,7 +48,7 @@ static int elfboot_exec ( struct image *image ) {
/* An ELF image has no callback interface, so we need to shut
* down before invoking it.
*/
- shutdown ( SHUTDOWN_BOOT );
+ shutdown_boot();
/* Jump to OS with flat physical addressing */
DBGC ( image, "ELF %p starting execution at %lx\n", image, entry );
diff --git a/src/arch/i386/image/multiboot.c b/src/arch/i386/image/multiboot.c
index 041f0f2a..3ed4d840 100644
--- a/src/arch/i386/image/multiboot.c
+++ b/src/arch/i386/image/multiboot.c
@@ -278,7 +278,7 @@ static int multiboot_exec ( struct image *image ) {
/* Multiboot images may not return and have no callback
* interface, so shut everything down prior to booting the OS.
*/
- shutdown ( SHUTDOWN_BOOT );
+ shutdown_boot();
/* Build memory map after unhiding bootloader memory regions as part of
* shutting everything down.
diff --git a/src/arch/i386/image/nbi.c b/src/arch/i386/image/nbi.c
index 67f0d511..804b2303 100644
--- a/src/arch/i386/image/nbi.c
+++ b/src/arch/i386/image/nbi.c
@@ -406,7 +406,7 @@ static int nbi_exec ( struct image *image ) {
/* Shut down now if NBI image will not return */
may_return = NBI_PROGRAM_RETURNS ( imgheader.flags );
if ( ! may_return )
- shutdown ( SHUTDOWN_BOOT );
+ shutdown_boot();
/* Execute NBI image */
if ( NBI_LINEAR_EXEC_ADDR ( imgheader.flags ) ) {
diff --git a/src/arch/i386/interface/pcbios/int13.c b/src/arch/i386/interface/pcbios/int13.c
index 1d973e77..a27dbad7 100644
--- a/src/arch/i386/interface/pcbios/int13.c
+++ b/src/arch/i386/interface/pcbios/int13.c
@@ -1209,8 +1209,10 @@ static int int13_hook ( struct uri *uri, unsigned int drive ) {
int13->cylinders, int13->heads, int13->sectors_per_track );
/* Hook INT 13 vector if not already hooked */
- if ( list_empty ( &int13s ) )
+ if ( list_empty ( &int13s ) ) {
int13_hook_vector();
+ devices_get();
+ }
/* Add to list of emulated drives */
list_add ( &int13->list, &int13s );
@@ -1277,8 +1279,10 @@ static void int13_unhook ( unsigned int drive ) {
DBGC ( int13, "INT13 drive %02x unregistered\n", int13->drive );
/* Unhook INT 13 vector if no more drives */
- if ( list_empty ( &int13s ) )
+ if ( list_empty ( &int13s ) ) {
+ devices_put();
int13_unhook_vector();
+ }
/* Drop list's reference to drive */
ref_put ( &int13->refcnt );
diff --git a/src/arch/i386/interface/pxe/pxe_call.c b/src/arch/i386/interface/pxe/pxe_call.c
index f6324bbf..f3208000 100644
--- a/src/arch/i386/interface/pxe/pxe_call.c
+++ b/src/arch/i386/interface/pxe/pxe_call.c
@@ -448,6 +448,7 @@ void pxe_activate ( struct net_device *netdev ) {
if ( ! int_1a_hooked ) {
hook_bios_interrupt ( 0x1a, ( unsigned int ) pxe_int_1a,
&pxe_int_1a_vector );
+ devices_get();
int_1a_hooked = 1;
}
@@ -475,6 +476,7 @@ int pxe_deactivate ( void ) {
strerror ( rc ) );
return rc;
}
+ devices_put();
int_1a_hooked = 0;
}
diff --git a/src/arch/i386/interface/pxe/pxe_preboot.c b/src/arch/i386/interface/pxe/pxe_preboot.c
index 7698df52..9e4853b0 100644
--- a/src/arch/i386/interface/pxe/pxe_preboot.c
+++ b/src/arch/i386/interface/pxe/pxe_preboot.c
@@ -290,7 +290,7 @@ PXENV_EXIT_t pxenv_stop_undi ( struct s_PXENV_STOP_UNDI *stop_undi ) {
pxe_deactivate();
/* Prepare for unload */
- shutdown ( SHUTDOWN_BOOT );
+ shutdown_boot();
/* Check to see if we still have any hooked interrupts */
if ( hooked_bios_interrupts != 0 ) {
diff --git a/src/arch/i386/interface/syslinux/comboot_call.c b/src/arch/i386/interface/syslinux/comboot_call.c
index 0c52b28a..95083270 100644
--- a/src/arch/i386/interface/syslinux/comboot_call.c
+++ b/src/arch/i386/interface/syslinux/comboot_call.c
@@ -531,7 +531,7 @@ static __asmcall void int22 ( struct i386_all_regs *ix86 ) {
break;
/* Perform final cleanup */
- shutdown ( SHUTDOWN_BOOT );
+ shutdown_boot();
/* Perform sequence of copies */
shuffle ( ix86->segs.es, ix86->regs.di, ix86->regs.cx );
@@ -608,7 +608,7 @@ static __asmcall void int22 ( struct i386_all_regs *ix86 ) {
break;
/* Perform final cleanup */
- shutdown ( SHUTDOWN_BOOT );
+ shutdown_boot();
/* Perform sequence of copies */
shuffle ( ix86->segs.es, ix86->regs.di, ix86->regs.cx );
diff --git a/src/core/device.c b/src/core/device.c
index cb2c23b0..dc182e03 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -35,6 +35,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
/** Registered root devices */
static LIST_HEAD ( devices );
+/** Device removal inhibition counter */
+int device_keep_count = 0;
+
/**
* Probe a root device
*
@@ -87,11 +90,11 @@ static void probe_devices ( void ) {
* Remove all devices
*
*/
-static void remove_devices ( int flags ) {
+static void remove_devices ( int booting __unused ) {
struct root_device *rootdev;
struct root_device *tmp;
- if ( flags & SHUTDOWN_KEEP_DEVICES ) {
+ if ( device_keep_count != 0 ) {
DBG ( "Refusing to remove devices on shutdown\n" );
return;
}
diff --git a/src/core/main.c b/src/core/main.c
index a1128dd0..e2b4e3e2 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -85,7 +85,7 @@ __asmcall int main ( void ) {
shell();
}
- shutdown ( SHUTDOWN_EXIT | shutdown_exit_flags );
+ shutdown_exit();
return 0;
}
diff --git a/src/drivers/net/efi/snponly.c b/src/drivers/net/efi/snponly.c
index 435ed4fb..6fcc54a0 100644
--- a/src/drivers/net/efi/snponly.c
+++ b/src/drivers/net/efi/snponly.c
@@ -114,13 +114,13 @@ struct root_device snp_root_device __root_device = {
/**
* Prepare for exit
*
- * @v flags Shutdown flags
+ * @v booting System is shutting down for OS boot
*/
-static void snponly_shutdown ( int flags ) {
+static void snponly_shutdown ( int booting ) {
/* If we are shutting down to boot an OS, make sure the SNP does not
* stay active.
*/
- if ( flags & SHUTDOWN_BOOT )
+ if ( booting )
snponly_dev.removal_state = EfiSimpleNetworkStopped;
}
diff --git a/src/image/efi_image.c b/src/image/efi_image.c
index 6b6600de..bf2e6f4a 100644
--- a/src/image/efi_image.c
+++ b/src/image/efi_image.c
@@ -39,7 +39,7 @@ static EFI_EVENT efi_shutdown_event;
*/
static EFIAPI void efi_shutdown_hook ( EFI_EVENT event __unused,
void *context __unused ) {
- shutdown ( SHUTDOWN_BOOT );
+ shutdown_boot();
}
/**
diff --git a/src/include/ipxe/device.h b/src/include/ipxe/device.h
index 068268ba..635ce59c 100644
--- a/src/include/ipxe/device.h
+++ b/src/include/ipxe/device.h
@@ -112,6 +112,24 @@ struct root_driver {
/** Declare a root device */
#define __root_device __table_entry ( ROOT_DEVICES, 01 )
+extern int device_keep_count;
+
+/**
+ * Prevent devices from being removed on shutdown
+ *
+ */
+static inline void devices_get ( void ) {
+ device_keep_count++;
+}
+
+/**
+ * Allow devices to be removed on shutdown
+ *
+ */
+static inline void devices_put ( void ) {
+ device_keep_count--;
+}
+
extern struct device * identify_device ( struct interface *intf );
#define identify_device_TYPE( object_type ) \
typeof ( struct device * ( object_type ) )
diff --git a/src/include/ipxe/init.h b/src/include/ipxe/init.h
index 10ff8695..954cda45 100644
--- a/src/include/ipxe/init.h
+++ b/src/include/ipxe/init.h
@@ -32,16 +32,6 @@ struct init_fn {
/** @} */
-/** Shutdown flags */
-enum shutdown_flags {
- /** Shutdown is in order to exit (return to iPXE's caller) */
- SHUTDOWN_EXIT = 0x0001,
- /** Shutdown is in order to boot an OS */
- SHUTDOWN_BOOT = 0x0002,
- /** Do not remove devices */
- SHUTDOWN_KEEP_DEVICES = 0x0004,
-};
-
/**
* A startup/shutdown function
*
@@ -50,7 +40,7 @@ enum shutdown_flags {
*/
struct startup_fn {
void ( * startup ) ( void );
- void ( * shutdown ) ( int flags );
+ void ( * shutdown ) ( int booting );
};
/** Startup/shutdown function table */
@@ -76,6 +66,22 @@ struct startup_fn {
extern void initialise ( void );
extern void startup ( void );
-extern void shutdown ( int flags );
+extern void shutdown ( int booting );
+
+/**
+ * Shut down system for OS boot
+ *
+ */
+static inline void shutdown_boot ( void ) {
+ shutdown ( 1 );
+}
+
+/**
+ * Shut down system for exit back to firmware
+ *
+ */
+static inline void shutdown_exit ( void ) {
+ shutdown ( 0 );
+}
#endif /* _IPXE_INIT_H */
diff --git a/src/include/usr/autoboot.h b/src/include/usr/autoboot.h
index e9abf833..32763bee 100644
--- a/src/include/usr/autoboot.h
+++ b/src/include/usr/autoboot.h
@@ -12,8 +12,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/in.h>
struct net_device;
-extern int shutdown_exit_flags;
-
extern int netboot ( struct net_device *netdev );
extern int autoboot ( void );
extern int boot_next_server_and_filename ( struct in_addr next_server,
diff --git a/src/usr/autoboot.c b/src/usr/autoboot.c
index 738c3cea..df152e3a 100644
--- a/src/usr/autoboot.c
+++ b/src/usr/autoboot.c
@@ -40,9 +40,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
*
*/
-/** Shutdown flags for exit */
-int shutdown_exit_flags = 0;
-
/**
* Perform PXE menu boot when PXE stack is not available
*/
@@ -193,7 +190,6 @@ int boot_root_path ( const char *root_path ) {
if ( fetch_intz_setting ( NULL, &keep_san_setting ) != 0 ) {
printf ( "Preserving connection to SAN device %#02x\n",
drive );
- shutdown_exit_flags |= SHUTDOWN_KEEP_DEVICES;
goto err_keep_san;
}