mirror of
https://github.com/ipxe/ipxe
synced 2025-12-13 15:31:42 +03:00
Add device description fields to struct device.
This commit is contained in:
@@ -72,7 +72,7 @@ int pcibios_read ( struct pci_device *pci, uint32_t command, uint32_t *value ){
|
|||||||
: "=a" ( status ), "=b" ( discard_b ),
|
: "=a" ( status ), "=b" ( discard_b ),
|
||||||
"=c" ( *value ), "=D" ( discard_D )
|
"=c" ( *value ), "=D" ( discard_D )
|
||||||
: "a" ( command >> 16 ), "D" ( command ),
|
: "a" ( command >> 16 ), "D" ( command ),
|
||||||
"b" ( ( pci->bus << 8 ) | pci->devfn )
|
"b" ( PCI_BUSDEVFN ( pci->bus, pci->devfn ) )
|
||||||
: "edx" );
|
: "edx" );
|
||||||
|
|
||||||
return ( ( status >> 8 ) & 0xff );
|
return ( ( status >> 8 ) & 0xff );
|
||||||
@@ -98,7 +98,7 @@ int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ){
|
|||||||
: "=a" ( status ), "=b" ( discard_b ),
|
: "=a" ( status ), "=b" ( discard_b ),
|
||||||
"=c" ( discard_c ), "=D" ( discard_D )
|
"=c" ( discard_c ), "=D" ( discard_D )
|
||||||
: "a" ( command >> 16 ), "D" ( command ),
|
: "a" ( command >> 16 ), "D" ( command ),
|
||||||
"b" ( ( pci->bus << 8 ) | pci->devfn ),
|
"b" ( PCI_BUSDEVFN ( pci->bus, pci->devfn ) ),
|
||||||
"c" ( value )
|
"c" ( value )
|
||||||
: "edx" );
|
: "edx" );
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ static int undipci_probe ( struct pci_device *pci,
|
|||||||
const struct pci_device_id *id __unused ) {
|
const struct pci_device_id *id __unused ) {
|
||||||
struct undi_device *undi;
|
struct undi_device *undi;
|
||||||
struct undi_rom *undirom;
|
struct undi_rom *undirom;
|
||||||
unsigned int busdevfn = ( ( pci->bus << 8 ) | pci->devfn );
|
unsigned int busdevfn = PCI_BUSDEVFN ( pci->bus, pci->devfn );
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Ignore non-network devices */
|
/* Ignore non-network devices */
|
||||||
@@ -99,6 +99,7 @@ static int undipci_probe ( struct pci_device *pci,
|
|||||||
/* Add to device hierarchy */
|
/* Add to device hierarchy */
|
||||||
snprintf ( undi->dev.name, sizeof ( undi->dev.name ),
|
snprintf ( undi->dev.name, sizeof ( undi->dev.name ),
|
||||||
"UNDI-%s", pci->dev.name );
|
"UNDI-%s", pci->dev.name );
|
||||||
|
memcpy ( &undi->dev.desc, &pci->dev.desc, sizeof ( undi->dev.desc ) );
|
||||||
undi->dev.parent = &pci->dev;
|
undi->dev.parent = &pci->dev;
|
||||||
INIT_LIST_HEAD ( &undi->dev.children );
|
INIT_LIST_HEAD ( &undi->dev.children );
|
||||||
list_add ( &undi->dev.siblings, &pci->dev.children );
|
list_add ( &undi->dev.siblings, &pci->dev.children );
|
||||||
|
|||||||
@@ -76,13 +76,13 @@ int undi_load ( struct undi_device *undi, struct undi_rom *undirom ) {
|
|||||||
/* Debug info */
|
/* Debug info */
|
||||||
DBGC ( undi, "UNDI %p loading UNDI ROM %p to CS %04x DS %04x for ",
|
DBGC ( undi, "UNDI %p loading UNDI ROM %p to CS %04x DS %04x for ",
|
||||||
undi, undirom, undi_loader.UNDI_CS, undi_loader.UNDI_DS );
|
undi, undirom, undi_loader.UNDI_CS, undi_loader.UNDI_DS );
|
||||||
if ( undi->pci_busdevfn != 0xffff ) {
|
if ( undi->pci_busdevfn != UNDI_NO_PCI_BUSDEVFN ) {
|
||||||
unsigned int bus = ( undi->pci_busdevfn >> 8 );
|
unsigned int bus = ( undi->pci_busdevfn >> 8 );
|
||||||
unsigned int devfn = ( undi->pci_busdevfn & 0xff );
|
unsigned int devfn = ( undi->pci_busdevfn & 0xff );
|
||||||
DBGC ( undi, "PCI %02x:%02x.%x\n",
|
DBGC ( undi, "PCI %02x:%02x.%x\n",
|
||||||
bus, PCI_SLOT ( devfn ), PCI_FUNC ( devfn ) );
|
bus, PCI_SLOT ( devfn ), PCI_FUNC ( devfn ) );
|
||||||
}
|
}
|
||||||
if ( undi->isapnp_csn != 0xffff ) {
|
if ( undi->isapnp_csn != UNDI_NO_ISAPNP_CSN ) {
|
||||||
DBGC ( undi, "ISAPnP(%04x) CSN %04x\n",
|
DBGC ( undi, "ISAPnP(%04x) CSN %04x\n",
|
||||||
undi->isapnp_read_port, undi->isapnp_csn );
|
undi->isapnp_read_port, undi->isapnp_csn );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,29 +49,41 @@
|
|||||||
* find.
|
* find.
|
||||||
*/
|
*/
|
||||||
static int undibus_probe ( struct root_device *rootdev ) {
|
static int undibus_probe ( struct root_device *rootdev ) {
|
||||||
|
struct undi_device *undi = &preloaded_undi;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Check for a valie preloaded UNDI device */
|
/* Check for a valie preloaded UNDI device */
|
||||||
if ( ! preloaded_undi.entry.segment ) {
|
if ( ! undi->entry.segment ) {
|
||||||
DBG ( "No preloaded UNDI device found!\n" );
|
DBG ( "No preloaded UNDI device found!\n" );
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add to device hierarchy */
|
/* Add to device hierarchy */
|
||||||
strncpy ( preloaded_undi.dev.name, "UNDI",
|
strncpy ( undi->dev.name, "UNDI",
|
||||||
( sizeof ( preloaded_undi.dev.name ) - 1 ) );
|
( sizeof ( undi->dev.name ) - 1 ) );
|
||||||
preloaded_undi.dev.parent = &rootdev->dev;
|
if ( undi->pci_busdevfn != UNDI_NO_PCI_BUSDEVFN ) {
|
||||||
list_add ( &preloaded_undi.dev.siblings, &rootdev->dev.children);
|
struct pci_device_description *pcidesc = &undi->dev.desc.pci;
|
||||||
INIT_LIST_HEAD ( &preloaded_undi.dev.children );
|
pcidesc->bus_type = BUS_TYPE_PCI;
|
||||||
|
pcidesc->busdevfn = undi->pci_busdevfn;
|
||||||
|
pcidesc->vendor = undi->pci_vendor;
|
||||||
|
pcidesc->device = undi->pci_device;
|
||||||
|
} else if ( undi->isapnp_csn != UNDI_NO_ISAPNP_CSN ) {
|
||||||
|
struct isapnp_device_description *isapnpdesc
|
||||||
|
= &undi->dev.desc.isapnp;
|
||||||
|
isapnpdesc->bus_type = BUS_TYPE_ISAPNP;
|
||||||
|
}
|
||||||
|
undi->dev.parent = &rootdev->dev;
|
||||||
|
list_add ( &undi->dev.siblings, &rootdev->dev.children);
|
||||||
|
INIT_LIST_HEAD ( &undi->dev.children );
|
||||||
|
|
||||||
/* Create network device */
|
/* Create network device */
|
||||||
if ( ( rc = undinet_probe ( &preloaded_undi ) ) != 0 )
|
if ( ( rc = undinet_probe ( undi ) ) != 0 )
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
list_del ( &preloaded_undi.dev.siblings );
|
list_del ( &undi->dev.siblings );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,8 +93,10 @@ static int undibus_probe ( struct root_device *rootdev ) {
|
|||||||
* @v rootdev UNDI bus root device
|
* @v rootdev UNDI bus root device
|
||||||
*/
|
*/
|
||||||
static void undibus_remove ( struct root_device *rootdev __unused ) {
|
static void undibus_remove ( struct root_device *rootdev __unused ) {
|
||||||
undinet_remove ( &preloaded_undi );
|
struct undi_device *undi = &preloaded_undi;
|
||||||
list_del ( &preloaded_undi.dev.siblings );
|
|
||||||
|
undinet_remove ( undi );
|
||||||
|
list_del ( &undi->dev.siblings );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** UNDI bus root device driver */
|
/** UNDI bus root device driver */
|
||||||
|
|||||||
@@ -26,12 +26,22 @@ struct undi_device {
|
|||||||
UINT16_t fbms;
|
UINT16_t fbms;
|
||||||
/** Free base memory prior to load */
|
/** Free base memory prior to load */
|
||||||
UINT16_t restore_fbms;
|
UINT16_t restore_fbms;
|
||||||
/** PCI bus:dev.fn, or 0xffff */
|
/** PCI bus:dev.fn, or @c UNDI_NO_PCI_BUSDEVFN */
|
||||||
UINT16_t pci_busdevfn;
|
UINT16_t pci_busdevfn;
|
||||||
/** ISAPnP card select number, or 0xffff */
|
/** ISAPnP card select number, or @c UNDI_NO_ISAPNP_CSN */
|
||||||
UINT16_t isapnp_csn;
|
UINT16_t isapnp_csn;
|
||||||
/** ISAPnP read port, or 0xffff */
|
/** ISAPnP read port, or @c UNDI_NO_ISAPNP_READ_PORT */
|
||||||
UINT16_t isapnp_read_port;
|
UINT16_t isapnp_read_port;
|
||||||
|
/** PCI vendor ID
|
||||||
|
*
|
||||||
|
* Filled in only for the preloaded UNDI device by pxeprefix.S
|
||||||
|
*/
|
||||||
|
UINT16_t pci_vendor;
|
||||||
|
/** PCI device ID
|
||||||
|
*
|
||||||
|
* Filled in only for the preloaded UNDI device by pxeprefix.S
|
||||||
|
*/
|
||||||
|
UINT16_t pci_device;
|
||||||
/** Padding */
|
/** Padding */
|
||||||
UINT16_t pad;
|
UINT16_t pad;
|
||||||
|
|
||||||
@@ -45,6 +55,15 @@ struct undi_device {
|
|||||||
void *priv;
|
void *priv;
|
||||||
} __attribute__ (( packed ));
|
} __attribute__ (( packed ));
|
||||||
|
|
||||||
|
/** PCI bus:dev.fn field is invalid */
|
||||||
|
#define UNDI_NO_PCI_BUSDEVFN 0xffff
|
||||||
|
|
||||||
|
/** ISAPnP card select number field is invalid */
|
||||||
|
#define UNDI_NO_ISAPNP_CSN 0xffff
|
||||||
|
|
||||||
|
/** ISAPnP read port field is invalid */
|
||||||
|
#define UNDI_NO_ISAPNP_READ_PORT 0xffff
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set UNDI driver-private data
|
* Set UNDI driver-private data
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ static inline int undi_load_pci ( struct undi_device *undi,
|
|||||||
struct undi_rom *undirom,
|
struct undi_rom *undirom,
|
||||||
unsigned int pci_busdevfn ) {
|
unsigned int pci_busdevfn ) {
|
||||||
undi->pci_busdevfn = pci_busdevfn;
|
undi->pci_busdevfn = pci_busdevfn;
|
||||||
undi->isapnp_csn = 0xffff;
|
undi->isapnp_csn = UNDI_NO_ISAPNP_CSN;
|
||||||
undi->isapnp_read_port = 0xffff;
|
undi->isapnp_read_port = UNDI_NO_ISAPNP_READ_PORT;
|
||||||
return undi_load ( undi, undirom );
|
return undi_load ( undi, undirom );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -220,7 +220,9 @@ get_physical_device:
|
|||||||
jmp no_physical_device
|
jmp no_physical_device
|
||||||
|
|
||||||
pci_physical_device:
|
pci_physical_device:
|
||||||
/* Record PCI bus:dev.fn */
|
/* Record PCI bus:dev.fn and vendor/device IDs */
|
||||||
|
movl ( pxe_parameter_structure + 0x03 ), %eax
|
||||||
|
movl %eax, pci_vendor
|
||||||
movw ( pxe_parameter_structure + 0x0b ), %ax
|
movw ( pxe_parameter_structure + 0x0b ), %ax
|
||||||
movw %ax, pci_busdevfn
|
movw %ax, pci_busdevfn
|
||||||
movw $10f, %si
|
movw $10f, %si
|
||||||
@@ -680,6 +682,9 @@ pci_busdevfn: .word 0xffff
|
|||||||
isapnp_csn: .word 0xffff
|
isapnp_csn: .word 0xffff
|
||||||
isapnp_read_port: .word 0xffff
|
isapnp_read_port: .word 0xffff
|
||||||
|
|
||||||
|
pci_vendor: .word 0
|
||||||
|
pci_device: .word 0
|
||||||
|
|
||||||
.equ undi_device_size, ( . - undi_device )
|
.equ undi_device_size, ( . - undi_device )
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|||||||
@@ -282,6 +282,10 @@ static int pcibus_probe ( struct root_device *rootdev ) {
|
|||||||
snprintf ( pci->dev.name, sizeof ( pci->dev.name ),
|
snprintf ( pci->dev.name, sizeof ( pci->dev.name ),
|
||||||
"PCI%02x:%02x.%x", bus,
|
"PCI%02x:%02x.%x", bus,
|
||||||
PCI_SLOT ( devfn ), PCI_FUNC ( devfn ) );
|
PCI_SLOT ( devfn ), PCI_FUNC ( devfn ) );
|
||||||
|
pci->dev.desc.bus_type = BUS_TYPE_PCI;
|
||||||
|
pci->dev.desc.pci.busdevfn = PCI_BUSDEVFN (bus, devfn);
|
||||||
|
pci->dev.desc.pci.vendor = pci->vendor;
|
||||||
|
pci->dev.desc.pci.device = pci->device;
|
||||||
pci->dev.parent = &rootdev->dev;
|
pci->dev.parent = &rootdev->dev;
|
||||||
list_add ( &pci->dev.siblings, &rootdev->dev.children);
|
list_add ( &pci->dev.siblings, &rootdev->dev.children);
|
||||||
INIT_LIST_HEAD ( &pci->dev.children );
|
INIT_LIST_HEAD ( &pci->dev.children );
|
||||||
|
|||||||
@@ -11,10 +11,58 @@
|
|||||||
#include <gpxe/list.h>
|
#include <gpxe/list.h>
|
||||||
#include <gpxe/tables.h>
|
#include <gpxe/tables.h>
|
||||||
|
|
||||||
|
/** A PCI device description */
|
||||||
|
struct pci_device_description {
|
||||||
|
/** Bus type
|
||||||
|
*
|
||||||
|
* Must be @c BUS_TYPE_PCI.
|
||||||
|
*/
|
||||||
|
unsigned int bus_type;
|
||||||
|
/** Bus:dev.fn address
|
||||||
|
*
|
||||||
|
* As constructed by PCI_BUSDEVFN().
|
||||||
|
*/
|
||||||
|
unsigned int busdevfn;
|
||||||
|
/** Vendor ID */
|
||||||
|
unsigned int vendor;
|
||||||
|
/** Device ID */
|
||||||
|
unsigned int device;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** PCI bus type */
|
||||||
|
#define BUS_TYPE_PCI 1
|
||||||
|
|
||||||
|
/** An ISAPnP device description */
|
||||||
|
struct isapnp_device_description {
|
||||||
|
/** Bus type
|
||||||
|
*
|
||||||
|
* Must be @c BUS_TYPE_ISAPNP.
|
||||||
|
*/
|
||||||
|
unsigned int bus_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** PCI bus type */
|
||||||
|
#define BUS_TYPE_ISAPNP 2
|
||||||
|
|
||||||
|
/** A hardware device description */
|
||||||
|
union device_description {
|
||||||
|
/** Bus type
|
||||||
|
*
|
||||||
|
* This must be a BUS_TYPE_XXX constant.
|
||||||
|
*/
|
||||||
|
unsigned int bus_type;
|
||||||
|
/** PCI device description */
|
||||||
|
struct pci_device_description pci;
|
||||||
|
/** ISAPnP device description */
|
||||||
|
struct isapnp_device_description isapnp;
|
||||||
|
};
|
||||||
|
|
||||||
/** A hardware device */
|
/** A hardware device */
|
||||||
struct device {
|
struct device {
|
||||||
/** Name */
|
/** Name */
|
||||||
char name[16];
|
char name[16];
|
||||||
|
/** Device description */
|
||||||
|
union device_description desc;
|
||||||
/** Devices on the same bus */
|
/** Devices on the same bus */
|
||||||
struct list_head siblings;
|
struct list_head siblings;
|
||||||
/** Devices attached to this device */
|
/** Devices attached to this device */
|
||||||
|
|||||||
@@ -307,9 +307,10 @@ struct pci_driver {
|
|||||||
/** Declare a PCI driver */
|
/** Declare a PCI driver */
|
||||||
#define __pci_driver __table ( struct pci_driver, pci_drivers, 01 )
|
#define __pci_driver __table ( struct pci_driver, pci_drivers, 01 )
|
||||||
|
|
||||||
#define PCI_DEVFN( slot, func ) ( ( (slot) << 3 ) | (func) )
|
#define PCI_DEVFN( slot, func ) ( ( (slot) << 3 ) | (func) )
|
||||||
#define PCI_SLOT( devfn ) ( ( (devfn) >> 3 ) & 0x1f )
|
#define PCI_SLOT( devfn ) ( ( (devfn) >> 3 ) & 0x1f )
|
||||||
#define PCI_FUNC( devfn ) ( (devfn) & 0x07 )
|
#define PCI_FUNC( devfn ) ( (devfn) & 0x07 )
|
||||||
|
#define PCI_BUSDEVFN( bus, devfn ) ( ( (bus) << 8 ) | (devfn) )
|
||||||
|
|
||||||
#define PCI_BASE_CLASS( class ) ( (class) >> 16 )
|
#define PCI_BASE_CLASS( class ) ( (class) >> 16 )
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user