Переглянути джерело

Implemented (untested) PXENV_START_UNDI.

tags/v0.9.3
Michael Brown 18 роки тому
джерело
коміт
0924cf678e

+ 1
- 1
src/drivers/bus/isapnp.c Переглянути файл

529
  *
529
  *
530
  */
530
  */
531
 static void isapnp_isolate ( void ) {
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
 	      isapnp_read_port <= ISAPNP_READ_PORT_MAX ;
533
 	      isapnp_read_port <= ISAPNP_READ_PORT_MAX ;
534
 	      isapnp_read_port += ISAPNP_READ_PORT_STEP ) {
534
 	      isapnp_read_port += ISAPNP_READ_PORT_STEP ) {
535
 		/* Avoid problematic locations such as the NE2000
535
 		/* Avoid problematic locations such as the NE2000

+ 6
- 1
src/include/gpxe/isapnp.h Переглянути файл

49
 /* Port addresses */
49
 /* Port addresses */
50
 #define ISAPNP_ADDRESS		0x279
50
 #define ISAPNP_ADDRESS		0x279
51
 #define ISAPNP_WRITE_DATA	0xa79
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
 					 * Linux ISAPnP starts at
54
 					 * Linux ISAPnP starts at
54
 					 * 0x213 with no explanatory
55
 					 * 0x213 with no explanatory
55
 					 * comment.  0x203 probably
56
 					 * comment.  0x203 probably
63
 					 * any value less than 16.
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
 /* Registers */
71
 /* Registers */
67
 #define ISAPNP_READPORT			0x00
72
 #define ISAPNP_READPORT			0x00
68
 #define ISAPNP_SERIALISOLATION 		0x01
73
 #define ISAPNP_SERIALISOLATION 		0x01

+ 6
- 5
src/include/gpxe/netdevice.h Переглянути файл

289
 }
289
 }
290
 
290
 
291
 extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
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
 extern void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf );
295
 extern void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf );
295
 extern int netdev_poll ( struct net_device *netdev, unsigned int rx_quota );
296
 extern int netdev_poll ( struct net_device *netdev, unsigned int rx_quota );
296
 extern struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev );
297
 extern struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev );
299
 extern int netdev_open ( struct net_device *netdev );
300
 extern int netdev_open ( struct net_device *netdev );
300
 extern void netdev_close ( struct net_device *netdev );
301
 extern void netdev_close ( struct net_device *netdev );
301
 extern void unregister_netdev ( struct net_device *netdev );
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
 extern int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
306
 extern int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
306
 		    struct net_protocol *net_protocol, const void *ll_dest );
307
 		    struct net_protocol *net_protocol, const void *ll_dest );
307
 extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
308
 extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,

+ 41
- 32
src/interface/pxe/pxe_preboot.c Переглянути файл

28
 #include <stdlib.h>
28
 #include <stdlib.h>
29
 #include <gpxe/uaccess.h>
29
 #include <gpxe/uaccess.h>
30
 #include <gpxe/dhcp.h>
30
 #include <gpxe/dhcp.h>
31
+#include <gpxe/device.h>
32
+#include <gpxe/netdevice.h>
33
+#include <gpxe/isapnp.h>
31
 #include <basemem_packet.h>
34
 #include <basemem_packet.h>
32
 #include "pxe.h"
35
 #include "pxe.h"
33
 #include "pxe_call.h"
36
 #include "pxe_call.h"
196
  * Status: working
199
  * Status: working
197
  */
200
  */
198
 PXENV_EXIT_t pxenv_start_undi ( struct s_PXENV_START_UNDI *start_undi ) {
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
 	start_undi->Status = PXENV_STATUS_SUCCESS;
244
 	start_undi->Status = PXENV_STATUS_SUCCESS;
236
 	return PXENV_EXIT_SUCCESS;
245
 	return PXENV_EXIT_SUCCESS;

+ 6
- 4
src/net/netdevice.c Переглянути файл

356
 /**
356
 /**
357
  * Get network device by PCI bus:dev.fn address
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
  * @ret netdev		Network device, or NULL
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
 	struct net_device *netdev;
365
 	struct net_device *netdev;
364
 
366
 
365
 	list_for_each_entry ( netdev, &net_devices, list ) {
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
 			return netdev;
370
 			return netdev;
369
 	}
371
 	}
370
 
372
 

Завантаження…
Відмінити
Зберегти