Browse Source

Implemented (untested) PXENV_START_UNDI.

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
0924cf678e

+ 1
- 1
src/drivers/bus/isapnp.c View File

@@ -529,7 +529,7 @@ static int isapnp_try_isolate ( void ) {
529 529
  *
530 530
  */
531 531
 static void isapnp_isolate ( void ) {
532
-	for ( isapnp_read_port = ISAPNP_READ_PORT_MIN ;
532
+	for ( isapnp_read_port = ISAPNP_READ_PORT_START ;
533 533
 	      isapnp_read_port <= ISAPNP_READ_PORT_MAX ;
534 534
 	      isapnp_read_port += ISAPNP_READ_PORT_STEP ) {
535 535
 		/* Avoid problematic locations such as the NE2000

+ 6
- 1
src/include/gpxe/isapnp.h View File

@@ -49,7 +49,8 @@
49 49
 /* Port addresses */
50 50
 #define ISAPNP_ADDRESS		0x279
51 51
 #define ISAPNP_WRITE_DATA	0xa79
52
-#define ISAPNP_READ_PORT_MIN	0x213	/* ISAPnP spec says 0x203, but
52
+#define ISAPNP_READ_PORT_MIN	0x203
53
+#define ISAPNP_READ_PORT_START	0x213	/* ISAPnP spec says 0x203, but
53 54
 					 * Linux ISAPnP starts at
54 55
 					 * 0x213 with no explanatory
55 56
 					 * comment.  0x203 probably
@@ -63,6 +64,10 @@
63 64
 					 * any value less than 16.
64 65
 					 */
65 66
 
67
+/* Card select numbers */
68
+#define ISAPNP_CSN_MIN		0x01
69
+#define ISAPNP_CSN_MAX		0x0f
70
+
66 71
 /* Registers */
67 72
 #define ISAPNP_READPORT			0x00
68 73
 #define ISAPNP_SERIALISOLATION 		0x01

+ 6
- 5
src/include/gpxe/netdevice.h View File

@@ -289,8 +289,9 @@ netdev_put ( struct net_device *netdev ) {
289 289
 }
290 290
 
291 291
 extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
292
-void netdev_tx_complete ( struct net_device *netdev, struct io_buffer *iobuf );
293
-void netdev_tx_complete_next ( struct net_device *netdev );
292
+extern void netdev_tx_complete ( struct net_device *netdev,
293
+				 struct io_buffer *iobuf );
294
+extern void netdev_tx_complete_next ( struct net_device *netdev );
294 295
 extern void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf );
295 296
 extern int netdev_poll ( struct net_device *netdev, unsigned int rx_quota );
296 297
 extern struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev );
@@ -299,9 +300,9 @@ extern int register_netdev ( struct net_device *netdev );
299 300
 extern int netdev_open ( struct net_device *netdev );
300 301
 extern void netdev_close ( struct net_device *netdev );
301 302
 extern void unregister_netdev ( struct net_device *netdev );
302
-struct net_device * find_netdev ( const char *name );
303
-struct net_device * find_pci_netdev ( unsigned int busdevfn );
304
-
303
+extern struct net_device * find_netdev ( const char *name );
304
+extern struct net_device * find_netdev_by_location ( unsigned int bus_type,
305
+						     unsigned int location );
305 306
 extern int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
306 307
 		    struct net_protocol *net_protocol, const void *ll_dest );
307 308
 extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,

+ 41
- 32
src/interface/pxe/pxe_preboot.c View File

@@ -28,6 +28,9 @@
28 28
 #include <stdlib.h>
29 29
 #include <gpxe/uaccess.h>
30 30
 #include <gpxe/dhcp.h>
31
+#include <gpxe/device.h>
32
+#include <gpxe/netdevice.h>
33
+#include <gpxe/isapnp.h>
31 34
 #include <basemem_packet.h>
32 35
 #include "pxe.h"
33 36
 #include "pxe_call.h"
@@ -196,41 +199,47 @@ PXENV_EXIT_t pxenv_restart_tftp ( struct s_PXENV_TFTP_READ_FILE
196 199
  * Status: working
197 200
  */
198 201
 PXENV_EXIT_t pxenv_start_undi ( struct s_PXENV_START_UNDI *start_undi ) {
202
+	unsigned int isapnp_read_port;
203
+	unsigned int isapnp_csn;
204
+	unsigned int pci_busdevfn;
205
+	unsigned int bus_type;
206
+	unsigned int location;
207
+	struct net_device *netdev;
208
+
209
+	DBG ( "PXENV_START_UNDI %04x:%04x:%04x",
210
+	      start_undi->AX, start_undi->BX, start_undi->DX );
211
+
212
+	/* Determine bus type and location */
213
+	isapnp_read_port = start_undi->DX;
214
+	isapnp_csn = start_undi->BX;
215
+	pci_busdevfn = start_undi->AX;
216
+
217
+	/* Use a heuristic to decide whether we are PCI or ISAPnP */
218
+	if ( ( isapnp_read_port >= ISAPNP_READ_PORT_MIN ) &&
219
+	     ( isapnp_read_port <= ISAPNP_READ_PORT_MAX ) &&
220
+	     ( isapnp_csn >= ISAPNP_CSN_MIN ) &&
221
+	     ( isapnp_csn <= ISAPNP_CSN_MAX ) ) {
222
+		bus_type = BUS_TYPE_ISAPNP;
223
+		location = isapnp_csn;
224
+	} else {
225
+		bus_type = BUS_TYPE_PCI;
226
+		location = pci_busdevfn;
227
+	}
199 228
 
200
-	DBG ( "PXENV_START_UNDI" );
201
-
202
-#if 0
203
-	/* Record PCI bus & devfn passed by caller, so we know which
204
-	 * NIC they want to use.
205
-	 *
206
-	 * If they don't match our already-existing NIC structure, set
207
-	 * values to ensure that the specified NIC is used at the next
208
-	 * call to pxe_intialise_nic().
209
-	 */
210
-	bus = ( start_undi->AX >> 8 ) & 0xff;
211
-	devfn = start_undi->AX & 0xff;
212
-
213
-#warning "device probing mechanism has completely changed"
214
-#if 0
215
-	if ( ( pci->dev.driver == NULL ) ||
216
-	     ( pci->dev.bus != bus ) || ( pci->dev.devfn != devfn ) ) {
217
-		/* This is quite a bit of a hack and relies on
218
-		 * knowledge of the internal operation of Etherboot's
219
-		 * probe mechanism.
220
-		 */
221
-		DBG ( " set PCI %hhx:%hhx.%hhx",
222
-		      bus, PCI_SLOT(devfn), PCI_FUNC(devfn) );
223
-		dev->type = BOOT_NIC;
224
-		dev->to_probe = PROBE_PCI;
225
-		memset ( &dev->state, 0, sizeof(dev->state) );
226
-		pci->advance = 1;
227
-		pci->dev.use_specified = 1;
228
-		pci->dev.bus = bus;
229
-		pci->dev.devfn = devfn;
229
+	/* Look for a matching net device */
230
+	netdev = find_netdev_by_location ( bus_type, location );
231
+	if ( ! netdev ) {
232
+		DBG ( " no net device found" );
233
+		start_undi->Status = PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC;
234
+		return PXENV_EXIT_FAILURE;
230 235
 	}
231
-#endif
236
+	DBG ( " using netdev %s", netdev->name );
232 237
 
233
-#endif
238
+	/* Save as PXE net device */
239
+	pxe_set_netdev ( netdev );
240
+
241
+	/* Hook INT 1A */
242
+	pxe_hook_int1a();
234 243
 
235 244
 	start_undi->Status = PXENV_STATUS_SUCCESS;
236 245
 	return PXENV_EXIT_SUCCESS;

+ 6
- 4
src/net/netdevice.c View File

@@ -356,15 +356,17 @@ struct net_device * find_netdev ( const char *name ) {
356 356
 /**
357 357
  * Get network device by PCI bus:dev.fn address
358 358
  *
359
- * @v busdevfn		PCI bus:dev.fn address
359
+ * @v bus_type		Bus type
360
+ * @v location		Bus location
360 361
  * @ret netdev		Network device, or NULL
361 362
  */
362
-struct net_device * find_pci_netdev ( unsigned int busdevfn ) {
363
+struct net_device * find_netdev_by_location ( unsigned int bus_type,
364
+					      unsigned int location ) {
363 365
 	struct net_device *netdev;
364 366
 
365 367
 	list_for_each_entry ( netdev, &net_devices, list ) {
366
-		if ( ( netdev->dev->desc.bus_type == BUS_TYPE_PCI ) &&
367
-		     ( netdev->dev->desc.location == busdevfn ) )
368
+		if ( ( netdev->dev->desc.bus_type == bus_type ) &&
369
+		     ( netdev->dev->desc.location == location ) )
368 370
 			return netdev;
369 371
 	}
370 372
 

Loading…
Cancel
Save