summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brown2007-01-29 16:21:10 +0100
committerMichael Brown2007-01-29 16:21:10 +0100
commit7d9267561b6ece59624e7dc0d521535d56278646 (patch)
tree45751d67c36f6927331646f71dd5e20d6a82697c /src
parentSplit bootsector execution code out into bootsector.c. (diff)
downloadipxe-7d9267561b6ece59624e7dc0d521535d56278646.tar.gz
ipxe-7d9267561b6ece59624e7dc0d521535d56278646.tar.xz
ipxe-7d9267561b6ece59624e7dc0d521535d56278646.zip
Don't call PXENV_STOP_UNDI in the kpxeprefix. This slighy breaks the
clean separation between loading and starting, but does mean that more PXE stacks survive the process.
Diffstat (limited to 'src')
-rw-r--r--src/arch/i386/drivers/net/undinet.c23
-rw-r--r--src/arch/i386/include/undi.h33
-rw-r--r--src/arch/i386/prefix/pxeprefix.S15
3 files changed, 46 insertions, 25 deletions
diff --git a/src/arch/i386/drivers/net/undinet.c b/src/arch/i386/drivers/net/undinet.c
index e479269a..835ec76d 100644
--- a/src/arch/i386/drivers/net/undinet.c
+++ b/src/arch/i386/drivers/net/undinet.c
@@ -605,15 +605,19 @@ int undinet_probe ( struct undi_device *undi ) {
DBGC ( undinic, "UNDINIC %p using UNDI %p\n", undinic, undi );
/* Hook in UNDI stack */
- memset ( &start_undi, 0, sizeof ( start_undi ) );
- start_undi.AX = undi->pci_busdevfn;
- start_undi.BX = undi->isapnp_csn;
- start_undi.DX = undi->isapnp_read_port;
- start_undi.ES = BIOS_SEG;
- start_undi.DI = find_pnp_bios();
- if ( ( rc = undinet_call ( undinic, PXENV_START_UNDI, &start_undi,
- sizeof ( start_undi ) ) ) != 0 )
- goto err_start_undi;
+ if ( ! ( undi->flags & UNDI_FL_STARTED ) ) {
+ memset ( &start_undi, 0, sizeof ( start_undi ) );
+ start_undi.AX = undi->pci_busdevfn;
+ start_undi.BX = undi->isapnp_csn;
+ start_undi.DX = undi->isapnp_read_port;
+ start_undi.ES = BIOS_SEG;
+ start_undi.DI = find_pnp_bios();
+ if ( ( rc = undinet_call ( undinic, PXENV_START_UNDI,
+ &start_undi,
+ sizeof ( start_undi ) ) ) != 0 )
+ goto err_start_undi;
+ }
+ undi->flags |= UNDI_FL_STARTED;
/* Bring up UNDI stack */
memset ( &undi_startup, 0, sizeof ( undi_startup ) );
@@ -703,6 +707,7 @@ void undinet_remove ( struct undi_device *undi ) {
memset ( &stop_undi, 0, sizeof ( stop_undi ) );
undinet_call ( undinic, PXENV_STOP_UNDI, &stop_undi,
sizeof ( stop_undi ) );
+ undi->flags &= ~UNDI_FL_STARTED;
/* Free network device */
free_netdev ( netdev );
diff --git a/src/arch/i386/include/undi.h b/src/arch/i386/include/undi.h
index f6e22e70..f6fb85fe 100644
--- a/src/arch/i386/include/undi.h
+++ b/src/arch/i386/include/undi.h
@@ -7,6 +7,8 @@
*
*/
+#ifndef ASSEMBLY
+
#include <gpxe/device.h>
#include <pxe_types.h>
@@ -42,8 +44,12 @@ struct undi_device {
* Filled in only for the preloaded UNDI device by pxeprefix.S
*/
UINT16_t pci_device;
- /** Padding */
- UINT16_t pad;
+ /** Flags
+ *
+ * This is the bitwise OR of zero or more UNDI_FL_XXX
+ * constants.
+ */
+ UINT16_t flags;
/** Generic device */
struct device dev;
@@ -55,15 +61,6 @@ struct undi_device {
void *priv;
} __attribute__ (( packed ));
-/** PCI bus:dev.fn field is invalid */
-#define UNDI_NO_PCI_BUSDEVFN 0xffff
-
-/** ISAPnP card select number field is invalid */
-#define UNDI_NO_ISAPNP_CSN 0xffff
-
-/** ISAPnP read port field is invalid */
-#define UNDI_NO_ISAPNP_READ_PORT 0xffff
-
/**
* Set UNDI driver-private data
*
@@ -84,4 +81,18 @@ static inline void * undi_get_drvdata ( struct undi_device *undi ) {
return undi->priv;
}
+#endif /* ASSEMBLY */
+
+/** PCI bus:dev.fn field is invalid */
+#define UNDI_NO_PCI_BUSDEVFN 0xffff
+
+/** ISAPnP card select number field is invalid */
+#define UNDI_NO_ISAPNP_CSN 0xffff
+
+/** ISAPnP read port field is invalid */
+#define UNDI_NO_ISAPNP_READ_PORT 0xffff
+
+/** UNDI flag: START_UNDI has been called */
+#define UNDI_FL_STARTED 0x0001
+
#endif /* _UNDI_H */
diff --git a/src/arch/i386/prefix/pxeprefix.S b/src/arch/i386/prefix/pxeprefix.S
index 8c091df6..ca1a00c9 100644
--- a/src/arch/i386/prefix/pxeprefix.S
+++ b/src/arch/i386/prefix/pxeprefix.S
@@ -10,6 +10,8 @@
.section ".prefix.data", "aw", @progbits
.code16
+#include <undi.h>
+
/*****************************************************************************
* Entry point: set operating context, print welcome message
*****************************************************************************
@@ -278,6 +280,7 @@ unload_base_code:
* Unload UNDI driver
*****************************************************************************
*/
+#ifndef PXELOADER_KEEP_UNDI
unload_undi:
/* Issue PXENV_STOP_UNDI */
movw $PXENV_STOP_UNDI, %bx
@@ -286,12 +289,13 @@ unload_undi:
call print_pxe_error
jmp 99f
1: /* Free base memory used by UNDI */
-#ifndef PXELOADER_KEEP_UNDI
movw undi_fbms_start, %si
movw undi_fbms_end, %di
call free_basemem
-#endif /* PXELOADER_KEEP_UNDI */
+ /* Clear UNDI_FL_STARTED */
+ andw $~UNDI_FL_STARTED, flags
99:
+#endif /* PXELOADER_KEEP_UNDI */
/*****************************************************************************
* Print remaining free base memory
@@ -678,12 +682,13 @@ entry_segment: .word 0
undi_fbms_start: .word 0
undi_fbms_end: .word 0
-pci_busdevfn: .word 0xffff
-isapnp_csn: .word 0xffff
-isapnp_read_port: .word 0xffff
+pci_busdevfn: .word UNDI_NO_PCI_BUSDEVFN
+isapnp_csn: .word UNDI_NO_ISAPNP_CSN
+isapnp_read_port: .word UNDI_NO_ISAPNP_READ_PORT
pci_vendor: .word 0
pci_device: .word 0
+flags: .word UNDI_FL_STARTED
.equ undi_device_size, ( . - undi_device )