mirror of https://github.com/ipxe/ipxe.git
Implemented (untested) PXENV_START_UNDI.
parent
30a442aef8
commit
0924cf678e
|
@ -529,7 +529,7 @@ static int isapnp_try_isolate ( void ) {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void isapnp_isolate ( void ) {
|
static void isapnp_isolate ( void ) {
|
||||||
for ( isapnp_read_port = ISAPNP_READ_PORT_MIN ;
|
for ( isapnp_read_port = ISAPNP_READ_PORT_START ;
|
||||||
isapnp_read_port <= ISAPNP_READ_PORT_MAX ;
|
isapnp_read_port <= ISAPNP_READ_PORT_MAX ;
|
||||||
isapnp_read_port += ISAPNP_READ_PORT_STEP ) {
|
isapnp_read_port += ISAPNP_READ_PORT_STEP ) {
|
||||||
/* Avoid problematic locations such as the NE2000
|
/* Avoid problematic locations such as the NE2000
|
||||||
|
|
|
@ -49,7 +49,8 @@
|
||||||
/* Port addresses */
|
/* Port addresses */
|
||||||
#define ISAPNP_ADDRESS 0x279
|
#define ISAPNP_ADDRESS 0x279
|
||||||
#define ISAPNP_WRITE_DATA 0xa79
|
#define ISAPNP_WRITE_DATA 0xa79
|
||||||
#define ISAPNP_READ_PORT_MIN 0x213 /* ISAPnP spec says 0x203, but
|
#define ISAPNP_READ_PORT_MIN 0x203
|
||||||
|
#define ISAPNP_READ_PORT_START 0x213 /* ISAPnP spec says 0x203, but
|
||||||
* Linux ISAPnP starts at
|
* Linux ISAPnP starts at
|
||||||
* 0x213 with no explanatory
|
* 0x213 with no explanatory
|
||||||
* comment. 0x203 probably
|
* comment. 0x203 probably
|
||||||
|
@ -63,6 +64,10 @@
|
||||||
* any value less than 16.
|
* any value less than 16.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Card select numbers */
|
||||||
|
#define ISAPNP_CSN_MIN 0x01
|
||||||
|
#define ISAPNP_CSN_MAX 0x0f
|
||||||
|
|
||||||
/* Registers */
|
/* Registers */
|
||||||
#define ISAPNP_READPORT 0x00
|
#define ISAPNP_READPORT 0x00
|
||||||
#define ISAPNP_SERIALISOLATION 0x01
|
#define ISAPNP_SERIALISOLATION 0x01
|
||||||
|
|
|
@ -289,8 +289,9 @@ netdev_put ( struct net_device *netdev ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
|
extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
|
||||||
void netdev_tx_complete ( struct net_device *netdev, struct io_buffer *iobuf );
|
extern void netdev_tx_complete ( struct net_device *netdev,
|
||||||
void netdev_tx_complete_next ( struct net_device *netdev );
|
struct io_buffer *iobuf );
|
||||||
|
extern void netdev_tx_complete_next ( struct net_device *netdev );
|
||||||
extern void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf );
|
extern void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf );
|
||||||
extern int netdev_poll ( struct net_device *netdev, unsigned int rx_quota );
|
extern int netdev_poll ( struct net_device *netdev, unsigned int rx_quota );
|
||||||
extern struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev );
|
extern struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev );
|
||||||
|
@ -299,9 +300,9 @@ extern int register_netdev ( struct net_device *netdev );
|
||||||
extern int netdev_open ( struct net_device *netdev );
|
extern int netdev_open ( struct net_device *netdev );
|
||||||
extern void netdev_close ( struct net_device *netdev );
|
extern void netdev_close ( struct net_device *netdev );
|
||||||
extern void unregister_netdev ( struct net_device *netdev );
|
extern void unregister_netdev ( struct net_device *netdev );
|
||||||
struct net_device * find_netdev ( const char *name );
|
extern struct net_device * find_netdev ( const char *name );
|
||||||
struct net_device * find_pci_netdev ( unsigned int busdevfn );
|
extern struct net_device * find_netdev_by_location ( unsigned int bus_type,
|
||||||
|
unsigned int location );
|
||||||
extern int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
|
extern int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
|
||||||
struct net_protocol *net_protocol, const void *ll_dest );
|
struct net_protocol *net_protocol, const void *ll_dest );
|
||||||
extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
|
extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <gpxe/uaccess.h>
|
#include <gpxe/uaccess.h>
|
||||||
#include <gpxe/dhcp.h>
|
#include <gpxe/dhcp.h>
|
||||||
|
#include <gpxe/device.h>
|
||||||
|
#include <gpxe/netdevice.h>
|
||||||
|
#include <gpxe/isapnp.h>
|
||||||
#include <basemem_packet.h>
|
#include <basemem_packet.h>
|
||||||
#include "pxe.h"
|
#include "pxe.h"
|
||||||
#include "pxe_call.h"
|
#include "pxe_call.h"
|
||||||
|
@ -196,41 +199,47 @@ PXENV_EXIT_t pxenv_restart_tftp ( struct s_PXENV_TFTP_READ_FILE
|
||||||
* Status: working
|
* Status: working
|
||||||
*/
|
*/
|
||||||
PXENV_EXIT_t pxenv_start_undi ( struct s_PXENV_START_UNDI *start_undi ) {
|
PXENV_EXIT_t pxenv_start_undi ( struct s_PXENV_START_UNDI *start_undi ) {
|
||||||
|
unsigned int isapnp_read_port;
|
||||||
|
unsigned int isapnp_csn;
|
||||||
|
unsigned int pci_busdevfn;
|
||||||
|
unsigned int bus_type;
|
||||||
|
unsigned int location;
|
||||||
|
struct net_device *netdev;
|
||||||
|
|
||||||
DBG ( "PXENV_START_UNDI" );
|
DBG ( "PXENV_START_UNDI %04x:%04x:%04x",
|
||||||
|
start_undi->AX, start_undi->BX, start_undi->DX );
|
||||||
|
|
||||||
#if 0
|
/* Determine bus type and location */
|
||||||
/* Record PCI bus & devfn passed by caller, so we know which
|
isapnp_read_port = start_undi->DX;
|
||||||
* NIC they want to use.
|
isapnp_csn = start_undi->BX;
|
||||||
*
|
pci_busdevfn = start_undi->AX;
|
||||||
* If they don't match our already-existing NIC structure, set
|
|
||||||
* values to ensure that the specified NIC is used at the next
|
|
||||||
* call to pxe_intialise_nic().
|
|
||||||
*/
|
|
||||||
bus = ( start_undi->AX >> 8 ) & 0xff;
|
|
||||||
devfn = start_undi->AX & 0xff;
|
|
||||||
|
|
||||||
#warning "device probing mechanism has completely changed"
|
/* Use a heuristic to decide whether we are PCI or ISAPnP */
|
||||||
#if 0
|
if ( ( isapnp_read_port >= ISAPNP_READ_PORT_MIN ) &&
|
||||||
if ( ( pci->dev.driver == NULL ) ||
|
( isapnp_read_port <= ISAPNP_READ_PORT_MAX ) &&
|
||||||
( pci->dev.bus != bus ) || ( pci->dev.devfn != devfn ) ) {
|
( isapnp_csn >= ISAPNP_CSN_MIN ) &&
|
||||||
/* This is quite a bit of a hack and relies on
|
( isapnp_csn <= ISAPNP_CSN_MAX ) ) {
|
||||||
* knowledge of the internal operation of Etherboot's
|
bus_type = BUS_TYPE_ISAPNP;
|
||||||
* probe mechanism.
|
location = isapnp_csn;
|
||||||
*/
|
} else {
|
||||||
DBG ( " set PCI %hhx:%hhx.%hhx",
|
bus_type = BUS_TYPE_PCI;
|
||||||
bus, PCI_SLOT(devfn), PCI_FUNC(devfn) );
|
location = pci_busdevfn;
|
||||||
dev->type = BOOT_NIC;
|
|
||||||
dev->to_probe = PROBE_PCI;
|
|
||||||
memset ( &dev->state, 0, sizeof(dev->state) );
|
|
||||||
pci->advance = 1;
|
|
||||||
pci->dev.use_specified = 1;
|
|
||||||
pci->dev.bus = bus;
|
|
||||||
pci->dev.devfn = devfn;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
/* Look for a matching net device */
|
||||||
|
netdev = find_netdev_by_location ( bus_type, location );
|
||||||
|
if ( ! netdev ) {
|
||||||
|
DBG ( " no net device found" );
|
||||||
|
start_undi->Status = PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC;
|
||||||
|
return PXENV_EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
DBG ( " using netdev %s", netdev->name );
|
||||||
|
|
||||||
|
/* Save as PXE net device */
|
||||||
|
pxe_set_netdev ( netdev );
|
||||||
|
|
||||||
|
/* Hook INT 1A */
|
||||||
|
pxe_hook_int1a();
|
||||||
|
|
||||||
start_undi->Status = PXENV_STATUS_SUCCESS;
|
start_undi->Status = PXENV_STATUS_SUCCESS;
|
||||||
return PXENV_EXIT_SUCCESS;
|
return PXENV_EXIT_SUCCESS;
|
||||||
|
|
|
@ -356,15 +356,17 @@ struct net_device * find_netdev ( const char *name ) {
|
||||||
/**
|
/**
|
||||||
* Get network device by PCI bus:dev.fn address
|
* Get network device by PCI bus:dev.fn address
|
||||||
*
|
*
|
||||||
* @v busdevfn PCI bus:dev.fn address
|
* @v bus_type Bus type
|
||||||
|
* @v location Bus location
|
||||||
* @ret netdev Network device, or NULL
|
* @ret netdev Network device, or NULL
|
||||||
*/
|
*/
|
||||||
struct net_device * find_pci_netdev ( unsigned int busdevfn ) {
|
struct net_device * find_netdev_by_location ( unsigned int bus_type,
|
||||||
|
unsigned int location ) {
|
||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
|
|
||||||
list_for_each_entry ( netdev, &net_devices, list ) {
|
list_for_each_entry ( netdev, &net_devices, list ) {
|
||||||
if ( ( netdev->dev->desc.bus_type == BUS_TYPE_PCI ) &&
|
if ( ( netdev->dev->desc.bus_type == bus_type ) &&
|
||||||
( netdev->dev->desc.location == busdevfn ) )
|
( netdev->dev->desc.location == location ) )
|
||||||
return netdev;
|
return netdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue