Browse Source

[undi] Ensure only one UNDI instance is loaded

Loading multiple UNDI instances would be useful in systems that have
several network cards with vendor PXE ROMs.  However, we cannot rely on
UNDI ROMs working correctly with multiple instances loaded
simultaneously.

The gPXE UNDI driver supports the following multi-NIC configurations:
1. Chainloading undionly.kpxe on a specific NIC.
2. Loading the UNDI driver for the first probed device and ignoring all
   other UNDI devices in the system.

This patch refuses to probe additional UNDI devices so there can never
be multiple instances of UNDI loaded.

Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
Signed-off-by: Marty Connor <mdc@etherboot.org>
tags/v1.20.1
Stefan Hajnoczi 14 years ago
parent
commit
b7af0aa34e
1 changed files with 12 additions and 0 deletions
  1. 12
    0
      src/arch/i386/drivers/net/undiload.c

+ 12
- 0
src/arch/i386/drivers/net/undiload.c View File

58
 	uint16_t exit;
58
 	uint16_t exit;
59
 	int rc;
59
 	int rc;
60
 
60
 
61
+	/* Only one UNDI instance may be loaded at any given time */
62
+	if ( undi_loader_entry.segment ) {
63
+		DBG ( "UNDI %p cannot load multiple instances\n", undi );
64
+		return -EBUSY;
65
+	}
66
+
61
 	/* Set up START_UNDI parameters */
67
 	/* Set up START_UNDI parameters */
62
 	memset ( &undi_loader, 0, sizeof ( undi_loader ) );
68
 	memset ( &undi_loader, 0, sizeof ( undi_loader ) );
63
 	undi_loader.AX = undi->pci_busdevfn;
69
 	undi_loader.AX = undi->pci_busdevfn;
109
 	gateA20_set();
115
 	gateA20_set();
110
 
116
 
111
 	if ( exit != PXENV_EXIT_SUCCESS ) {
117
 	if ( exit != PXENV_EXIT_SUCCESS ) {
118
+		/* Clear entry point */
119
+		memset ( &undi_loader_entry, 0, sizeof ( undi_loader_entry ) );
120
+
112
 		rc = -undi_loader.Status;
121
 		rc = -undi_loader.Status;
113
 		if ( rc == 0 ) /* Paranoia */
122
 		if ( rc == 0 ) /* Paranoia */
114
 			rc = -EIO;
123
 			rc = -EIO;
151
 
160
 
152
 	DBGC ( undi, "UNDI %p unloading\n", undi );
161
 	DBGC ( undi, "UNDI %p unloading\n", undi );
153
 
162
 
163
+	/* Clear entry point */
164
+	memset ( &undi_loader_entry, 0, sizeof ( undi_loader_entry ) );
165
+
154
 	/* Erase signatures */
166
 	/* Erase signatures */
155
 	if ( undi->pxenv.segment )
167
 	if ( undi->pxenv.segment )
156
 		put_real ( dead, undi->pxenv.segment, undi->pxenv.offset );
168
 		put_real ( dead, undi->pxenv.segment, undi->pxenv.offset );

Loading…
Cancel
Save