summaryrefslogtreecommitdiffstats
path: root/src/arch
diff options
context:
space:
mode:
authorMichael Brown2009-06-28 21:08:58 +0200
committerMichael Brown2009-06-28 21:11:32 +0200
commit07b5be33413a23e150b84aed41881dfa056e41df (patch)
treebb541ff9199e174e0e35b23dd96cf2e52260a58b /src/arch
parent[pxe] Make pxe_init_structures() an initialisation function (diff)
downloadipxe-07b5be33413a23e150b84aed41881dfa056e41df.tar.gz
ipxe-07b5be33413a23e150b84aed41881dfa056e41df.tar.xz
ipxe-07b5be33413a23e150b84aed41881dfa056e41df.zip
[pxe] Create pxe_[de]activate() wrapper functions
Merge the pxe_set_netdev()+pxe_[un]hook_int1a() pattern into a single pxe_[de]activate() call.
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/i386/image/pxe_image.c15
-rw-r--r--src/arch/i386/include/pxe_call.h6
-rw-r--r--src/arch/i386/interface/pxe/pxe_call.c66
-rw-r--r--src/arch/i386/interface/pxe/pxe_preboot.c14
4 files changed, 61 insertions, 40 deletions
diff --git a/src/arch/i386/image/pxe_image.c b/src/arch/i386/image/pxe_image.c
index fde8f09b..63429f87 100644
--- a/src/arch/i386/image/pxe_image.c
+++ b/src/arch/i386/image/pxe_image.c
@@ -44,27 +44,24 @@ struct image_type pxe_image_type __image_type ( PROBE_PXE );
* @ret rc Return status code
*/
static int pxe_exec ( struct image *image ) {
+ struct net_device *netdev;
int rc;
- /* Ensure that PXE stack is ready to use */
- pxe_hook_int1a();
-
/* Arbitrarily pick the most recently opened network device */
- pxe_set_netdev ( last_opened_netdev() );
-
- /* Many things will break if pxe_netdev is NULL */
- if ( ! pxe_netdev ) {
+ if ( ( netdev = last_opened_netdev() ) == NULL ) {
DBGC ( image, "IMAGE %p could not locate PXE net device\n",
image );
return -ENODEV;
}
+ /* Activate PXE */
+ pxe_activate ( netdev );
+
/* Start PXE NBP */
rc = pxe_start_nbp();
/* Deactivate PXE */
- pxe_set_netdev ( NULL );
- pxe_unhook_int1a();
+ pxe_deactivate();
return rc;
}
diff --git a/src/arch/i386/include/pxe_call.h b/src/arch/i386/include/pxe_call.h
index 05d70516..50667e62 100644
--- a/src/arch/i386/include/pxe_call.h
+++ b/src/arch/i386/include/pxe_call.h
@@ -11,6 +11,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <pxe_api.h>
#include <realmode.h>
+struct net_device;
+
/** PXE load address segment */
#define PXE_LOAD_SEGMENT 0
@@ -28,8 +30,8 @@ extern struct s_PXE __text16 ( ppxe );
extern struct s_PXENV __text16 ( pxenv );
#define pxenv __use_text16 ( pxenv )
-extern void pxe_hook_int1a ( void );
-extern int pxe_unhook_int1a ( void );
+extern void pxe_activate ( struct net_device *netdev );
+extern int pxe_deactivate ( void );
extern int pxe_start_nbp ( void );
extern __asmcall void pxe_api_call ( struct i386_all_regs *ix86 );
diff --git a/src/arch/i386/interface/pxe/pxe_call.c b/src/arch/i386/interface/pxe/pxe_call.c
index e15a8c14..705afcab 100644
--- a/src/arch/i386/interface/pxe/pxe_call.c
+++ b/src/arch/i386/interface/pxe/pxe_call.c
@@ -37,6 +37,9 @@ extern struct segoff __text16 ( pxe_int_1a_vector );
/** INT 1A handler */
extern void pxe_int_1a ( void );
+/** INT 1A hooked flag */
+static int int_1a_hooked = 0;
+
/** A function pointer to hold any PXE API call
*
* Used by pxe_api_call() to avoid large swathes of duplicated code.
@@ -365,25 +368,6 @@ __asmcall void pxe_loader_call ( struct i386_all_regs *ix86 ) {
}
/**
- * Hook INT 1A for PXE
- *
- */
-void pxe_hook_int1a ( void ) {
- hook_bios_interrupt ( 0x1a, ( unsigned int ) pxe_int_1a,
- &pxe_int_1a_vector );
-}
-
-/**
- * Unhook INT 1A for PXE
- *
- * @ret rc Return status code
- */
-int pxe_unhook_int1a ( void ) {
- return unhook_bios_interrupt ( 0x1a, ( unsigned int ) pxe_int_1a,
- &pxe_int_1a_vector );
-}
-
-/**
* Calculate byte checksum as used by PXE
*
* @v data Data
@@ -436,6 +420,50 @@ struct init_fn pxe_init_fn __init_fn ( INIT_NORMAL ) = {
};
/**
+ * Activate PXE stack
+ *
+ * @v netdev Net device to use as PXE net device
+ */
+void pxe_activate ( struct net_device *netdev ) {
+
+ /* Ensure INT 1A is hooked */
+ if ( ! int_1a_hooked ) {
+ hook_bios_interrupt ( 0x1a, ( unsigned int ) pxe_int_1a,
+ &pxe_int_1a_vector );
+ int_1a_hooked = 1;
+ }
+
+ /* Set PXE network device */
+ pxe_set_netdev ( netdev );
+}
+
+/**
+ * Deactivate PXE stack
+ *
+ * @ret rc Return status code
+ */
+int pxe_deactivate ( void ) {
+ int rc;
+
+ /* Clear PXE network device */
+ pxe_set_netdev ( NULL );
+
+ /* Ensure INT 1A is unhooked, if possible */
+ if ( int_1a_hooked ) {
+ if ( ( rc = unhook_bios_interrupt ( 0x1a,
+ (unsigned int) pxe_int_1a,
+ &pxe_int_1a_vector ))!= 0){
+ DBG ( "Could not unhook INT 1A: %s\n",
+ strerror ( rc ) );
+ return rc;
+ }
+ int_1a_hooked = 0;
+ }
+
+ return 0;
+}
+
+/**
* Start PXE NBP at 0000:7c00
*
* @ret rc Return status code
diff --git a/src/arch/i386/interface/pxe/pxe_preboot.c b/src/arch/i386/interface/pxe/pxe_preboot.c
index 5ea06e92..21461a5a 100644
--- a/src/arch/i386/interface/pxe/pxe_preboot.c
+++ b/src/arch/i386/interface/pxe/pxe_preboot.c
@@ -296,11 +296,8 @@ PXENV_EXIT_t pxenv_start_undi ( struct s_PXENV_START_UNDI *start_undi ) {
}
DBG ( " using netdev %s", netdev->name );
- /* Save as PXE net device */
- pxe_set_netdev ( netdev );
-
- /* Hook INT 1A */
- pxe_hook_int1a();
+ /* Activate PXE */
+ pxe_activate ( netdev );
start_undi->Status = PXENV_STATUS_SUCCESS;
return PXENV_EXIT_SUCCESS;
@@ -313,11 +310,8 @@ PXENV_EXIT_t pxenv_start_undi ( struct s_PXENV_START_UNDI *start_undi ) {
PXENV_EXIT_t pxenv_stop_undi ( struct s_PXENV_STOP_UNDI *stop_undi ) {
DBG ( "PXENV_STOP_UNDI" );
- /* Unhook INT 1A */
- pxe_unhook_int1a();
-
- /* Clear PXE net device */
- pxe_set_netdev ( NULL );
+ /* Deactivate PXE */
+ pxe_deactivate();
/* Prepare for unload */
shutdown ( SHUTDOWN_BOOT );