Browse Source

Merge branch 'master' of /pub/scm/gpxe

tags/v0.9.3
Marty Connor 17 years ago
parent
commit
4bcfe7507b

+ 48
- 1
src/arch/i386/drivers/net/undinet.c View File

45
 	unsigned int irq;
45
 	unsigned int irq;
46
 	/** Currently processing ISR */
46
 	/** Currently processing ISR */
47
 	int isr_processing;
47
 	int isr_processing;
48
+	/** Bug workarounds */
49
+	int hacks;
48
 };
50
 };
49
 
51
 
52
+/**
53
+ * @defgroup undi_hacks UNDI workarounds
54
+ * @{
55
+ */
56
+
57
+/** Work around Etherboot 5.4 bugs */
58
+#define UNDI_HACK_EB54		0x0001
59
+
60
+/** @} */
61
+
50
 static void undinet_close ( struct net_device *netdev );
62
 static void undinet_close ( struct net_device *netdev );
51
 
63
 
52
 /*****************************************************************************
64
 /*****************************************************************************
245
 static volatile uint8_t __text16 ( trigger_count ) = 0;
257
 static volatile uint8_t __text16 ( trigger_count ) = 0;
246
 #define trigger_count __use_text16 ( trigger_count )
258
 #define trigger_count __use_text16 ( trigger_count )
247
 
259
 
260
+/** Last observed trigger count */
261
+static unsigned int last_trigger_count = 0;
262
+
248
 /**
263
 /**
249
  * Hook UNDI interrupt service routine
264
  * Hook UNDI interrupt service routine
250
  *
265
  *
292
  * @ret triggered	ISR has been triggered since last check
307
  * @ret triggered	ISR has been triggered since last check
293
  */
308
  */
294
 static int undinet_isr_triggered ( void ) {
309
 static int undinet_isr_triggered ( void ) {
295
-	static unsigned int last_trigger_count = 0;
296
 	unsigned int this_trigger_count;
310
 	unsigned int this_trigger_count;
297
 
311
 
298
 	/* Read trigger_count.  Do this only once; it is volatile */
312
 	/* Read trigger_count.  Do this only once; it is volatile */
333
 	size_t len = iob_len ( iobuf );
347
 	size_t len = iob_len ( iobuf );
334
 	int rc;
348
 	int rc;
335
 
349
 
350
+	/* Technically, we ought to make sure that the previous
351
+	 * transmission has completed before we re-use the buffer.
352
+	 * However, many PXE stacks (including at least some Intel PXE
353
+	 * stacks and Etherboot 5.4) fail to generate TX completions.
354
+	 * In practice this won't be a problem, since our TX datapath
355
+	 * has a very low packet volume and we can get away with
356
+	 * assuming that a TX will be complete by the time we want to
357
+	 * transmit the next packet.
358
+	 */
359
+
336
 	/* Copy packet to UNDI I/O buffer */
360
 	/* Copy packet to UNDI I/O buffer */
337
 	if ( len > sizeof ( basemem_packet ) )
361
 	if ( len > sizeof ( basemem_packet ) )
338
 		len = sizeof ( basemem_packet );
362
 		len = sizeof ( basemem_packet );
460
 					 undi_isr.Frame.segment,
484
 					 undi_isr.Frame.segment,
461
 					 undi_isr.Frame.offset, frag_len );
485
 					 undi_isr.Frame.offset, frag_len );
462
 			if ( iob_len ( iobuf ) == len ) {
486
 			if ( iob_len ( iobuf ) == len ) {
487
+				/* Whole packet received; deliver it */
463
 				netdev_rx ( netdev, iobuf );
488
 				netdev_rx ( netdev, iobuf );
464
 				iobuf = NULL;
489
 				iobuf = NULL;
465
 				--rx_quota;
490
 				--rx_quota;
491
+				/* Etherboot 5.4 fails to return all packets
492
+				 * under mild load; pretend it retriggered.
493
+				 */
494
+				if ( undinic->hacks & UNDI_HACK_EB54 )
495
+					--last_trigger_count;
466
 			}
496
 			}
467
 			break;
497
 			break;
468
 		case PXENV_UNDI_ISR_OUT_DONE:
498
 		case PXENV_UNDI_ISR_OUT_DONE:
582
 	struct s_PXENV_UNDI_STARTUP undi_startup;
612
 	struct s_PXENV_UNDI_STARTUP undi_startup;
583
 	struct s_PXENV_UNDI_INITIALIZE undi_initialize;
613
 	struct s_PXENV_UNDI_INITIALIZE undi_initialize;
584
 	struct s_PXENV_UNDI_GET_INFORMATION undi_info;
614
 	struct s_PXENV_UNDI_GET_INFORMATION undi_info;
615
+	struct s_PXENV_UNDI_GET_IFACE_INFO undi_iface;
585
 	struct s_PXENV_UNDI_SHUTDOWN undi_shutdown;
616
 	struct s_PXENV_UNDI_SHUTDOWN undi_shutdown;
586
 	struct s_PXENV_UNDI_CLEANUP undi_cleanup;
617
 	struct s_PXENV_UNDI_CLEANUP undi_cleanup;
587
 	struct s_PXENV_STOP_UNDI stop_undi;
618
 	struct s_PXENV_STOP_UNDI stop_undi;
639
 	DBGC ( undinic, "UNDINIC %p is %s on IRQ %d\n",
670
 	DBGC ( undinic, "UNDINIC %p is %s on IRQ %d\n",
640
 	       undinic, eth_ntoa ( netdev->ll_addr ), undinic->irq );
671
 	       undinic, eth_ntoa ( netdev->ll_addr ), undinic->irq );
641
 
672
 
673
+	/* Get interface information */
674
+	memset ( &undi_iface, 0, sizeof ( undi_iface ) );
675
+	if ( ( rc = undinet_call ( undinic, PXENV_UNDI_GET_IFACE_INFO,
676
+				   &undi_iface,
677
+				   sizeof ( undi_iface ) ) ) != 0 )
678
+		goto err_undi_get_iface_info;
679
+	DBGC ( undinic, "UNDINIC %p has type %s and link speed %ld\n",
680
+	       undinic, undi_iface.IfaceType, undi_iface.LinkSpeed );
681
+	if ( strncmp ( ( ( char * ) undi_iface.IfaceType ), "Etherboot",
682
+		       sizeof ( undi_iface.IfaceType ) ) == 0 ) {
683
+		DBGC ( undinic, "UNDINIC %p Etherboot 5.4 workaround enabled\n",
684
+		       undinic );
685
+		undinic->hacks |= UNDI_HACK_EB54;
686
+	}
687
+
642
 	/* Point to NIC specific routines */
688
 	/* Point to NIC specific routines */
643
 	netdev->open	 = undinet_open;
689
 	netdev->open	 = undinet_open;
644
 	netdev->close	 = undinet_close;
690
 	netdev->close	 = undinet_close;
653
 	return 0;
699
 	return 0;
654
 
700
 
655
  err_register:
701
  err_register:
702
+ err_undi_get_iface_info:
656
  err_bad_irq:
703
  err_bad_irq:
657
  err_undi_get_information:
704
  err_undi_get_information:
658
  err_undi_initialize:
705
  err_undi_initialize:

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

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

+ 8
- 3
src/drivers/net/legacy.c View File

57
 	}
57
 	}
58
 }
58
 }
59
 
59
 
60
-static int legacy_open ( struct net_device *netdev __unused ) {
60
+static int legacy_open ( struct net_device *netdev ) {
61
+	struct nic *nic = netdev->priv;
62
+
63
+	nic->nic_op->irq ( nic, ENABLE );
61
 	return 0;
64
 	return 0;
62
 }
65
 }
63
 
66
 
64
-static void legacy_close ( struct net_device *netdev __unused ) {
65
-	/* Nothing to do */
67
+static void legacy_close ( struct net_device *netdev ) {
68
+	struct nic *nic = netdev->priv;
69
+
70
+	nic->nic_op->irq ( nic, DISABLE );
66
 }
71
 }
67
 
72
 
68
 int legacy_probe ( void *hwdev,
73
 int legacy_probe ( void *hwdev,

+ 0
- 23
src/drivers/net/pnic.c View File

160
 	return 0;
160
 	return 0;
161
 }
161
 }
162
 
162
 
163
-/**************************************************************************
164
-IRQ - Handle card interrupt status
165
-***************************************************************************/
166
-#if 0
167
-static void pnic_irq ( struct net_device *netdev, irq_action_t action ) {
168
-	struct pnic *pnic = netdev->priv;
169
-	uint8_t enabled;
170
-
171
-	switch ( action ) {
172
-	case DISABLE :
173
-	case ENABLE :
174
-		enabled = ( action == ENABLE ? 1 : 0 );
175
-		pnic_command ( pnic, PNIC_CMD_MASK_IRQ,
176
-			       &enabled, sizeof ( enabled ), NULL, 0, NULL );
177
-		break;
178
-	case FORCE :
179
-		pnic_command ( pnic, PNIC_CMD_FORCE_IRQ,
180
-			       NULL, 0, NULL, 0, NULL );
181
-		break;
182
-	}
183
-}
184
-#endif
185
-
186
 /**************************************************************************
163
 /**************************************************************************
187
 OPEN - Open network device
164
 OPEN - Open network device
188
 ***************************************************************************/
165
 ***************************************************************************/

+ 1
- 30
src/drivers/net/rtl8139.c View File

380
 
380
 
381
 	/* Check for space in TX ring */
381
 	/* Check for space in TX ring */
382
 	if ( rtl->tx.iobuf[rtl->tx.next] != NULL ) {
382
 	if ( rtl->tx.iobuf[rtl->tx.next] != NULL ) {
383
-		printf ( "TX overflow\n" );
384
-		free_iob ( iobuf );
383
+		DBG ( "TX overflow\n" );
385
 		return -ENOBUFS;
384
 		return -ENOBUFS;
386
 	}
385
 	}
387
 
386
 
472
 	}
471
 	}
473
 }
472
 }
474
 
473
 
475
-#if 0
476
-static void rtl_irq(struct nic *nic, irq_action_t action)
477
-{
478
-	unsigned int mask;
479
-	/* Bit of a guess as to which interrupts we should allow */
480
-	unsigned int interested = ROK | RER | RXOVW | FOVW | SERR;
481
-
482
-	switch ( action ) {
483
-	case DISABLE :
484
-	case ENABLE :
485
-		mask = inw(rtl->ioaddr + IntrMask);
486
-		mask = mask & ~interested;
487
-		if ( action == ENABLE ) mask = mask | interested;
488
-		outw(mask, rtl->ioaddr + IntrMask);
489
-		break;
490
-	case FORCE :
491
-		/* Apparently writing a 1 to this read-only bit of a
492
-		 * read-only and otherwise unrelated register will
493
-		 * force an interrupt.  If you ever want to see how
494
-		 * not to write a datasheet, read the one for the
495
-		 * RTL8139...
496
-		 */
497
-		outb(EROK, rtl->ioaddr + RxEarlyStatus);
498
-		break;
499
-	}
500
-}
501
-#endif
502
-
503
 /**
474
 /**
504
  * Probe PCI device
475
  * Probe PCI device
505
  *
476
  *

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

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 View File

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 View File

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;

+ 5
- 8
src/interface/pxe/pxe_undi.c View File

394
 
394
 
395
 /* PXENV_UNDI_FORCE_INTERRUPT
395
 /* PXENV_UNDI_FORCE_INTERRUPT
396
  *
396
  *
397
- * Status: working
397
+ * Status: won't implement (would require driver API changes for no
398
+ * perceptible benefit)
398
  */
399
  */
399
 PXENV_EXIT_t pxenv_undi_force_interrupt ( struct s_PXENV_UNDI_FORCE_INTERRUPT
400
 PXENV_EXIT_t pxenv_undi_force_interrupt ( struct s_PXENV_UNDI_FORCE_INTERRUPT
400
 					  *undi_force_interrupt ) {
401
 					  *undi_force_interrupt ) {
401
 	DBG ( "PXENV_UNDI_FORCE_INTERRUPT" );
402
 	DBG ( "PXENV_UNDI_FORCE_INTERRUPT" );
402
 
403
 
403
-#if 0
404
-	eth_irq ( FORCE );
405
-#endif
406
-
407
-	undi_force_interrupt->Status = PXENV_STATUS_SUCCESS;
408
-	return PXENV_EXIT_SUCCESS;
404
+	undi_force_interrupt->Status = PXENV_STATUS_UNSUPPORTED;
405
+	return PXENV_EXIT_FAILURE;
409
 }
406
 }
410
 
407
 
411
 /* PXENV_UNDI_GET_MCAST_ADDRESS
408
 /* PXENV_UNDI_GET_MCAST_ADDRESS
483
 	 * Most PXE stacks seem to take this approach.
480
 	 * Most PXE stacks seem to take this approach.
484
 	 */
481
 	 */
485
 	snprintf ( ( char * ) undi_get_iface_info->IfaceType,
482
 	snprintf ( ( char * ) undi_get_iface_info->IfaceType,
486
-		   sizeof ( undi_get_iface_info->IfaceType ), "Etherboot" );
483
+		   sizeof ( undi_get_iface_info->IfaceType ), "gPXE" );
487
 	undi_get_iface_info->LinkSpeed = 10000000; /* 10 Mbps */
484
 	undi_get_iface_info->LinkSpeed = 10000000; /* 10 Mbps */
488
 	undi_get_iface_info->ServiceFlags = 0;
485
 	undi_get_iface_info->ServiceFlags = 0;
489
 	memset ( undi_get_iface_info->Reserved, 0,
486
 	memset ( undi_get_iface_info->Reserved, 0,

+ 8
- 0
src/net/ipv4.c View File

141
  * @v dest		Final destination address
141
  * @v dest		Final destination address
142
  * @ret dest		Next hop destination address
142
  * @ret dest		Next hop destination address
143
  * @ret miniroute	Routing table entry to use, or NULL if no route
143
  * @ret miniroute	Routing table entry to use, or NULL if no route
144
+ *
145
+ * If the route requires use of a gateway, the next hop destination
146
+ * address will be overwritten with the gateway address.
144
  */
147
  */
145
 static struct ipv4_miniroute * ipv4_route ( struct in_addr *dest ) {
148
 static struct ipv4_miniroute * ipv4_route ( struct in_addr *dest ) {
146
 	struct ipv4_miniroute *miniroute;
149
 	struct ipv4_miniroute *miniroute;
147
 	int local;
150
 	int local;
148
 	int has_gw;
151
 	int has_gw;
149
 
152
 
153
+	/* Never attempt to route the broadcast address */
154
+	if ( dest->s_addr == INADDR_BROADCAST )
155
+		return NULL;
156
+
157
+	/* Find first usable route in routing table */
150
 	list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
158
 	list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
151
 		local = ( ( ( dest->s_addr ^ miniroute->address.s_addr )
159
 		local = ( ( ( dest->s_addr ^ miniroute->address.s_addr )
152
 			    & miniroute->netmask.s_addr ) == 0 );
160
 			    & miniroute->netmask.s_addr ) == 0 );

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

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
 

Loading…
Cancel
Save