Don't call PXENV_STOP_UNDI in the kpxeprefix. This slighy breaks the
authorMichael Brown <mcb30@etherboot.org>
Mon, 29 Jan 2007 15:21:10 +0000 (15:21 +0000)
committerMichael Brown <mcb30@etherboot.org>
Mon, 29 Jan 2007 15:21:10 +0000 (15:21 +0000)
clean separation between loading and starting, but does mean that more
PXE stacks survive the process.

src/arch/i386/drivers/net/undinet.c
src/arch/i386/include/undi.h
src/arch/i386/prefix/pxeprefix.S

index e479269..835ec76 100644 (file)
@@ -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 );
index f6e22e7..f6fb85f 100644 (file)
@@ -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 */
index 8c091df..ca1a00c 100644 (file)
@@ -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 )