diff -urN gpxe-0.9.7/src/arch/i386/prefix/pxeprefix.S gpxe-0.9.7-etherbootworkaround/src/arch/i386/prefix/pxeprefix.S
--- gpxe-0.9.7/src/arch/i386/prefix/pxeprefix.S	2009-03-01 21:23:42.000000000 -0500
+++ gpxe-0.9.7-etherbootworkaround/src/arch/i386/prefix/pxeprefix.S	2009-08-21 20:36:55.000000000 -0400
@@ -1,8 +1,11 @@
 #define PXENV_UNDI_SHUTDOWN		0x0005
 #define	PXENV_UNDI_GET_NIC_TYPE		0x0012
+#define PXENV_UNDI_GET_IFACE_INFO	0x0013
 #define	PXENV_STOP_UNDI			0x0015
 #define PXENV_UNLOAD_STACK		0x0070
 
+#define PXE_HACK_EB54			0x0001
+
 	.text
 	.arch i386
 	.org 0
@@ -11,6 +14,8 @@
 #include <undi.h>
 
 #define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) )
+#define EB_MAGIC_1 ( 'E' + ( 't' << 8 ) + ( 'h' << 16 ) + ( 'e' << 24 ) )
+#define EB_MAGIC_2 ( 'r' + ( 'b' << 8 ) + ( 'o' << 16 ) + ( 'o' << 24 ) )
 
 /*****************************************************************************
  * Entry point:	set operating context, print welcome message
@@ -309,8 +314,6 @@
 	movw	$10f, %si
 	call	print_message
 	call	print_pci_busdevfn
-	movb	$0x0a, %al
-	call	print_character
 	jmp	99f
 	.section ".prefix.data", "aw", @progbits
 10:	.asciz	"         UNDI device is PCI "
@@ -321,12 +324,47 @@
 	movw	$10f, %si
 	call	print_message
 	.section ".prefix.data", "aw", @progbits
-10:	.asciz	"         Unable to determine UNDI physical device\n"
+10:	.asciz	"         Unable to determine UNDI physical device"
 	.previous
 
 99:
 
 /*****************************************************************************
+ * Determine interface type
+ *****************************************************************************
+ */
+get_iface_type:
+	/* Issue PXENV_UNDI_GET_IFACE_INFO */
+	movw	$PXENV_UNDI_GET_IFACE_INFO, %bx
+	call	pxe_call
+	jnc	1f
+	call	print_pxe_error
+	jmp	99f
+1:	/* Print interface type */
+	movw	$10f, %si
+	call	print_message
+	leaw	( pxe_parameter_structure + 0x02 ), %si
+	call	print_message
+	.section ".prefix.data", "aw", @progbits
+10:	.asciz	", type "
+	.previous
+	/* Check for "Etherboot" interface type */
+	cmpl	$EB_MAGIC_1, ( pxe_parameter_structure + 0x02 )
+	jne	99f
+	cmpl	$EB_MAGIC_2, ( pxe_parameter_structure + 0x06 )
+	jne	99f
+	movw	$10f, %si
+	call	print_message
+	.section ".prefix.data", "aw", @progbits
+10:	.asciz	" (workaround enabled)"
+	.previous
+	/* Flag Etherboot workarounds as required */
+	orw	$PXE_HACK_EB54, pxe_hacks
+
+99:	movb	$0x0a, %al
+	call	print_character
+
+/*****************************************************************************
  * Leave NIC in a safe state
  *****************************************************************************
  */
@@ -339,6 +377,14 @@
 	call	print_pxe_error
 1:
 unload_base_code:
+	/* Etherboot treats PXENV_UNLOAD_STACK as PXENV_STOP_UNDI, so
+	 * we must not issue this call if the underlying stack is
+	 * Etherboot and we were not intending to issue a PXENV_STOP_UNDI.
+	 */
+#ifdef PXELOADER_KEEP_UNDI
+	testw	$PXE_HACK_EB54, pxe_hacks
+	jnz	99f
+#endif /* PXELOADER_KEEP_UNDI */
 	/* Issue PXENV_UNLOAD_STACK */
 	movw	$PXENV_UNLOAD_STACK, %bx
 	call	pxe_call
@@ -551,7 +597,9 @@
 	testw	%ax, %ax
 	jz	1f
 	stc
-1:	/* Restore registers and return */
+1:	/* Clear direction flag, for the sake of sanity */
+	cld
+	/* Restore registers and return */
 	popw	%es
 	popw	%di
 	ret
@@ -595,7 +643,7 @@
 pxe_esp:		.long 0
 pxe_ss:			.word 0
 
-pxe_parameter_structure: .fill 20
+pxe_parameter_structure: .fill 64
 
 undi_code_segoff:
 undi_code_size:		.word 0
@@ -605,6 +653,8 @@
 undi_data_size:		.word 0
 undi_data_segment:	.word 0
 
+pxe_hacks:		.word 0
+
 /* The following fields are part of a struct undi_device */
 
 undi_device:
