Browse Source

pxe_netdev now holds a reference to the network device.

Use generic fields in struct device_description rather than assuming
that the struct device * is contained within a pci_device or
isapnp_device; this assumption is broken when using the undionly
driver.

Add PXENV_UNDI_SET_STATION_ADDRESS.
tags/v0.9.3
Michael Brown 17 years ago
parent
commit
5f17089b14

+ 10
- 2
src/arch/i386/image/pxe_image.c View File

40
  */
40
  */
41
 static int pxe_exec ( struct image *image __unused ) {
41
 static int pxe_exec ( struct image *image __unused ) {
42
 	struct net_device *netdev;
42
 	struct net_device *netdev;
43
+	int rc;
43
 
44
 
44
 	/* Ensure that PXE stack is ready to use */
45
 	/* Ensure that PXE stack is ready to use */
45
 	pxe_init_structures();
46
 	pxe_init_structures();
47
 
48
 
48
 	/* Arbitrarily pick the first open network device to use for PXE */
49
 	/* Arbitrarily pick the first open network device to use for PXE */
49
 	for_each_netdev ( netdev ) {
50
 	for_each_netdev ( netdev ) {
50
-		pxe_netdev = netdev;
51
+		pxe_set_netdev ( netdev );
51
 		break;
52
 		break;
52
 	}
53
 	}
53
 
54
 
54
-	return pxe_start_nbp();
55
+	/* Start PXE NBP */
56
+	rc = pxe_start_nbp();
57
+
58
+	/* Deactivate PXE */
59
+	pxe_set_netdev ( NULL );
60
+	pxe_unhook_int1a();
61
+
62
+	return rc;
55
 }
63
 }
56
 
64
 
57
 /**
65
 /**

+ 2
- 0
src/drivers/bus/isapnp.c View File

705
 			isapnp->dev.desc.bus_type = BUS_TYPE_ISAPNP;
705
 			isapnp->dev.desc.bus_type = BUS_TYPE_ISAPNP;
706
 			isapnp->dev.desc.vendor = isapnp->vendor_id;
706
 			isapnp->dev.desc.vendor = isapnp->vendor_id;
707
 			isapnp->dev.desc.device = isapnp->prod_id;
707
 			isapnp->dev.desc.device = isapnp->prod_id;
708
+			isapnp->dev.desc.ioaddr = isapnp->ioaddr;
709
+			isapnp->dev.desc.irq = isapnp->irqno;
708
 			isapnp->dev.parent = &rootdev->dev;
710
 			isapnp->dev.parent = &rootdev->dev;
709
 			list_add ( &isapnp->dev.siblings,
711
 			list_add ( &isapnp->dev.siblings,
710
 				   &rootdev->dev.children );
712
 				   &rootdev->dev.children );

+ 3
- 0
src/drivers/bus/pci.c View File

286
 			pci->dev.desc.location = PCI_BUSDEVFN (bus, devfn);
286
 			pci->dev.desc.location = PCI_BUSDEVFN (bus, devfn);
287
 			pci->dev.desc.vendor = pci->vendor;
287
 			pci->dev.desc.vendor = pci->vendor;
288
 			pci->dev.desc.device = pci->device;
288
 			pci->dev.desc.device = pci->device;
289
+			pci->dev.desc.class = pci->class;
290
+			pci->dev.desc.ioaddr = pci->ioaddr;
291
+			pci->dev.desc.irq = pci->irq;
289
 			pci->dev.parent = &rootdev->dev;
292
 			pci->dev.parent = &rootdev->dev;
290
 			list_add ( &pci->dev.siblings, &rootdev->dev.children);
293
 			list_add ( &pci->dev.siblings, &rootdev->dev.children);
291
 			INIT_LIST_HEAD ( &pci->dev.children );
294
 			INIT_LIST_HEAD ( &pci->dev.children );

+ 6
- 0
src/include/gpxe/device.h View File

27
 	unsigned int vendor;
27
 	unsigned int vendor;
28
 	/** Device ID */
28
 	/** Device ID */
29
 	unsigned int device;
29
 	unsigned int device;
30
+	/** Device class */
31
+	unsigned long class;
32
+	/** I/O address */
33
+	unsigned long ioaddr;
34
+	/** IRQ */
35
+	unsigned int irq;
30
 };
36
 };
31
 
37
 
32
 /** PCI bus type */
38
 /** PCI bus type */

+ 2
- 0
src/include/pxe.h View File

137
 
137
 
138
 extern struct net_device *pxe_netdev;
138
 extern struct net_device *pxe_netdev;
139
 
139
 
140
+extern void pxe_set_netdev ( struct net_device *netdev );
141
+
140
 #endif /* PXE_H */
142
 #endif /* PXE_H */

+ 14
- 2
src/interface/pxe/pxe.c View File

22
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
  */
23
  */
24
 
24
 
25
-#include "dev.h"
25
+#include <gpxe/netdevice.h>
26
 #include "pxe.h"
26
 #include "pxe.h"
27
 
27
 
28
-#warning "pxe_netdev should hold a persistent reference to the net device"
29
 struct net_device *pxe_netdev = NULL;
28
 struct net_device *pxe_netdev = NULL;
30
 
29
 
30
+/**
31
+ * Set network device as current PXE network device
32
+ *
33
+ * @v netdev		Network device, or NULL
34
+ */
35
+void pxe_set_netdev ( struct net_device *netdev ) {
36
+	if ( pxe_netdev )
37
+		netdev_put ( pxe_netdev );
38
+	pxe_netdev = NULL;
39
+	if ( netdev )
40
+		pxe_netdev = netdev_get ( netdev );
41
+}
42
+
31
 #if 0
43
 #if 0
32
 
44
 
33
 /* Global pointer to currently installed PXE stack */
45
 /* Global pointer to currently installed PXE stack */

+ 27
- 53
src/interface/pxe/pxe_undi.c View File

24
 
24
 
25
 #include <stdint.h>
25
 #include <stdint.h>
26
 #include <string.h>
26
 #include <string.h>
27
+#include <byteswap.h>
27
 #include <gpxe/netdevice.h>
28
 #include <gpxe/netdevice.h>
28
 #include <gpxe/device.h>
29
 #include <gpxe/device.h>
29
 #include <gpxe/pci.h>
30
 #include <gpxe/pci.h>
30
-#include <gpxe/isapnp.h>
31
 #include <gpxe/if_ether.h>
31
 #include <gpxe/if_ether.h>
32
 #include <gpxe/shutdown.h>
32
 #include <gpxe/shutdown.h>
33
 #include "pxe.h"
33
 #include "pxe.h"
200
 
200
 
201
 /* PXENV_UNDI_SET_STATION_ADDRESS
201
 /* PXENV_UNDI_SET_STATION_ADDRESS
202
  *
202
  *
203
- * Status: working (deliberately incomplete)
203
+ * Status: working
204
  */
204
  */
205
 PXENV_EXIT_t 
205
 PXENV_EXIT_t 
206
 pxenv_undi_set_station_address ( struct s_PXENV_UNDI_SET_STATION_ADDRESS
206
 pxenv_undi_set_station_address ( struct s_PXENV_UNDI_SET_STATION_ADDRESS
207
 				 *undi_set_station_address ) {
207
 				 *undi_set_station_address ) {
208
+
208
 	DBG ( "PXENV_UNDI_SET_STATION_ADDRESS" );
209
 	DBG ( "PXENV_UNDI_SET_STATION_ADDRESS" );
209
 
210
 
210
-#if 0
211
-	/* We don't offer a facility to set the MAC address; this
212
-	 * would require adding extra code to all the Etherboot
213
-	 * drivers, for very little benefit.  If we're setting it to
214
-	 * the current value anyway then return success, otherwise
215
-	 * return UNSUPPORTED.
211
+	/* If adapter is open, the change will have no effect; return
212
+	 * an error
216
 	 */
213
 	 */
217
-	if ( memcmp ( nic.node_addr,
218
-		      &undi_set_station_address->StationAddress,
219
-		      ETH_ALEN ) == 0 ) {
220
-		undi_set_station_address->Status = PXENV_STATUS_SUCCESS;
221
-		return PXENV_EXIT_SUCCESS;
214
+	if ( pxe_netdev->state & NETDEV_OPEN ) {
215
+		undi_set_station_address->Status =
216
+			PXENV_STATUS_UNDI_INVALID_STATE;
217
+		return PXENV_EXIT_FAILURE;
222
 	}
218
 	}
223
-#endif
224
 
219
 
225
-	undi_set_station_address->Status = PXENV_STATUS_UNSUPPORTED;
226
-	return PXENV_EXIT_FAILURE;
220
+	/* Update MAC address */
221
+	memcpy ( pxe_netdev->ll_addr,
222
+		 &undi_set_station_address->StationAddress,
223
+		 pxe_netdev->ll_protocol->ll_addr_len );
224
+
225
+	undi_set_station_address = PXENV_STATUS_SUCCESS;
226
+	return PXENV_EXIT_SUCCESS;
227
 }
227
 }
228
 
228
 
229
 /* PXENV_UNDI_SET_PACKET_FILTER
229
 /* PXENV_UNDI_SET_PACKET_FILTER
248
 					  *undi_get_information ) {
248
 					  *undi_get_information ) {
249
 	struct device *dev = pxe_netdev->dev;
249
 	struct device *dev = pxe_netdev->dev;
250
 	struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
250
 	struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
251
-	unsigned int ioaddr;
252
-	unsigned int irqno;
253
 
251
 
254
 	DBG ( "PXENV_UNDI_GET_INFORMATION" );
252
 	DBG ( "PXENV_UNDI_GET_INFORMATION" );
255
 
253
 
256
-	switch ( dev->desc.bus_type ) {
257
-	case BUS_TYPE_PCI: {
258
-		struct pci_device *pci =
259
-			container_of ( dev, struct pci_device, dev );
260
-
261
-		ioaddr = pci->ioaddr;
262
-		irqno = pci->irq;
263
-		break; }
264
-	case BUS_TYPE_ISAPNP: {
265
-		struct isapnp_device *isapnp =
266
-			container_of ( dev, struct isapnp_device, dev );
267
-
268
-		ioaddr = isapnp->ioaddr;
269
-		irqno = isapnp->irqno;
270
-		break; }
271
-	default:
272
-		undi_get_information->Status = PXENV_STATUS_FAILURE;
273
-		return PXENV_EXIT_FAILURE;
274
-	}
275
-
276
-	undi_get_information->BaseIo = ioaddr;
277
-	undi_get_information->IntNumber = irqno;
254
+	undi_get_information->BaseIo = dev->desc.ioaddr;
255
+	undi_get_information->IntNumber = dev->desc.irq;
278
 	/* Cheat: assume all cards can cope with this */
256
 	/* Cheat: assume all cards can cope with this */
279
 	undi_get_information->MaxTranUnit = ETH_MAX_MTU;
257
 	undi_get_information->MaxTranUnit = ETH_MAX_MTU;
280
 	undi_get_information->HwType = ntohs ( ll_protocol->ll_proto );
258
 	undi_get_information->HwType = ntohs ( ll_protocol->ll_proto );
384
 
362
 
385
 	switch ( dev->desc.bus_type ) {
363
 	switch ( dev->desc.bus_type ) {
386
 	case BUS_TYPE_PCI: {
364
 	case BUS_TYPE_PCI: {
387
-		struct pci_device *pci =
388
-			container_of ( dev, struct pci_device, dev );
389
 		struct pci_nic_info *info = &undi_get_nic_type->info.pci;
365
 		struct pci_nic_info *info = &undi_get_nic_type->info.pci;
390
 
366
 
391
 		undi_get_nic_type->NicType = PCI_NIC;
367
 		undi_get_nic_type->NicType = PCI_NIC;
392
-		info->Vendor_ID = pci->vendor;
393
-		info->Dev_ID = pci->device;
394
-		info->Base_Class = PCI_BASE_CLASS ( pci->class );
395
-		info->Sub_Class = PCI_SUB_CLASS ( pci->class );
396
-		info->Prog_Intf = PCI_PROG_INTF ( pci->class );
397
-		info->BusDevFunc = PCI_BUSDEVFN ( pci->bus, pci->devfn );
368
+		info->Vendor_ID = dev->desc.vendor;
369
+		info->Dev_ID = dev->desc.device;
370
+		info->Base_Class = PCI_BASE_CLASS ( dev->desc.class );
371
+		info->Sub_Class = PCI_SUB_CLASS ( dev->desc.class );
372
+		info->Prog_Intf = PCI_PROG_INTF ( dev->desc.class );
373
+		info->BusDevFunc = dev->desc.location;
398
 		/* Cheat: remaining fields are probably unnecessary,
374
 		/* Cheat: remaining fields are probably unnecessary,
399
 		 * and would require adding extra code to pci.c.
375
 		 * and would require adding extra code to pci.c.
400
 		 */
376
 		 */
402
 		undi_get_nic_type->info.pci.SubDevice_ID = 0xffff;
378
 		undi_get_nic_type->info.pci.SubDevice_ID = 0xffff;
403
 		break; }
379
 		break; }
404
 	case BUS_TYPE_ISAPNP: {
380
 	case BUS_TYPE_ISAPNP: {
405
-		struct isapnp_device *isapnp =
406
-			container_of ( dev, struct isapnp_device, dev );
407
 		struct pnp_nic_info *info = &undi_get_nic_type->info.pnp;
381
 		struct pnp_nic_info *info = &undi_get_nic_type->info.pnp;
408
 
382
 
409
 		undi_get_nic_type->NicType = PnP_NIC;
383
 		undi_get_nic_type->NicType = PnP_NIC;
410
-		info->EISA_Dev_ID = ( ( isapnp->vendor_id << 16 ) |
411
-				      isapnp->prod_id );
412
-		info->CardSelNum = isapnp->csn;
384
+		info->EISA_Dev_ID = ( ( dev->desc.vendor << 16 ) |
385
+				      dev->desc.device );
386
+		info->CardSelNum = dev->desc.location;
413
 		/* Cheat: remaining fields are probably unnecessary,
387
 		/* Cheat: remaining fields are probably unnecessary,
414
 		 * and would require adding extra code to isapnp.c.
388
 		 * and would require adding extra code to isapnp.c.
415
 		 */
389
 		 */

Loading…
Cancel
Save