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 #include @@ -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 + /***************************************************************************** * 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 )