mirror of
https://github.com/xcat2/xNBA.git
synced 2024-11-22 09:31:51 +00:00
[pci] Add pci_find_next() to iterate over existent PCI devices
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
parent
2b869786c5
commit
6d910559b3
@ -171,8 +171,20 @@ void adjust_pci_device ( struct pci_device *pci ) {
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int pci_read_config ( struct pci_device *pci ) {
|
||||
uint16_t busdevfn;
|
||||
uint8_t hdrtype;
|
||||
uint32_t tmp;
|
||||
|
||||
/* Ignore all but the first function on non-multifunction devices */
|
||||
if ( PCI_FUNC ( pci->busdevfn ) != 0 ) {
|
||||
busdevfn = pci->busdevfn;
|
||||
pci->busdevfn = PCI_FIRST_FUNC ( pci->busdevfn );
|
||||
pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
|
||||
pci->busdevfn = busdevfn;
|
||||
if ( ! ( hdrtype & 0x80 ) )
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Check for physical device presence */
|
||||
pci_read_config_dword ( pci, PCI_VENDOR_ID, &tmp );
|
||||
if ( ( tmp == 0xffffffff ) || ( tmp == 0 ) )
|
||||
@ -203,6 +215,32 @@ int pci_read_config ( struct pci_device *pci ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find next device on PCI bus
|
||||
*
|
||||
* @v pci PCI device to fill in
|
||||
* @v busdevfn Starting bus:dev.fn address
|
||||
* @ret busdevfn Bus:dev.fn address of next PCI device, or negative error
|
||||
*/
|
||||
int pci_find_next ( struct pci_device *pci, unsigned int busdevfn ) {
|
||||
static unsigned int end;
|
||||
int rc;
|
||||
|
||||
/* Determine number of PCI buses */
|
||||
if ( ! end )
|
||||
end = PCI_BUSDEVFN ( pci_num_bus(), 0, 0 );
|
||||
|
||||
/* Find next PCI device, if any */
|
||||
for ( ; busdevfn < end ; busdevfn++ ) {
|
||||
memset ( pci, 0, sizeof ( *pci ) );
|
||||
pci_init ( pci, busdevfn );
|
||||
if ( ( rc = pci_read_config ( pci ) ) == 0 )
|
||||
return busdevfn;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find driver for PCI device
|
||||
*
|
||||
@ -276,14 +314,10 @@ void pci_remove ( struct pci_device *pci ) {
|
||||
*/
|
||||
static int pcibus_probe ( struct root_device *rootdev ) {
|
||||
struct pci_device *pci = NULL;
|
||||
unsigned int num_bus;
|
||||
unsigned int busdevfn;
|
||||
uint8_t hdrtype = 0;
|
||||
int busdevfn = 0;
|
||||
int rc;
|
||||
|
||||
num_bus = pci_num_bus();
|
||||
for ( busdevfn = 0 ; busdevfn < PCI_BUSDEVFN ( num_bus, 0, 0 ) ;
|
||||
busdevfn++ ) {
|
||||
for ( busdevfn = 0 ; 1 ; busdevfn++ ) {
|
||||
|
||||
/* Allocate struct pci_device */
|
||||
if ( ! pci )
|
||||
@ -292,22 +326,11 @@ static int pcibus_probe ( struct root_device *rootdev ) {
|
||||
rc = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
memset ( pci, 0, sizeof ( *pci ) );
|
||||
pci_init ( pci, busdevfn );
|
||||
|
||||
/* Skip all but the first function on
|
||||
* non-multifunction cards
|
||||
*/
|
||||
if ( PCI_FUNC ( busdevfn ) == 0 ) {
|
||||
pci_read_config_byte ( pci, PCI_HEADER_TYPE,
|
||||
&hdrtype );
|
||||
} else if ( ! ( hdrtype & 0x80 ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Read device configuration */
|
||||
if ( ( rc = pci_read_config ( pci ) ) != 0 )
|
||||
continue;
|
||||
/* Find next PCI device, if any */
|
||||
busdevfn = pci_find_next ( pci, busdevfn );
|
||||
if ( busdevfn < 0 )
|
||||
break;
|
||||
|
||||
/* Look for a driver */
|
||||
if ( ( rc = pci_find_driver ( pci ) ) != 0 ) {
|
||||
|
@ -351,6 +351,7 @@ struct pci_driver {
|
||||
#define PCI_FUNC( busdevfn ) ( ( (busdevfn) >> 0 ) & 0x07 )
|
||||
#define PCI_BUSDEVFN( bus, slot, func ) \
|
||||
( ( (bus) << 8 ) | ( (slot) << 3 ) | ( (func) << 0 ) )
|
||||
#define PCI_FIRST_FUNC( busdevfn ) ( (busdevfn) & ~0x07 )
|
||||
|
||||
#define PCI_BASE_CLASS( class ) ( (class) >> 16 )
|
||||
#define PCI_SUB_CLASS( class ) ( ( (class) >> 8 ) & 0xff )
|
||||
@ -385,6 +386,7 @@ extern void adjust_pci_device ( struct pci_device *pci );
|
||||
extern unsigned long pci_bar_start ( struct pci_device *pci,
|
||||
unsigned int reg );
|
||||
extern int pci_read_config ( struct pci_device *pci );
|
||||
extern int pci_find_next ( struct pci_device *pci, unsigned int busdevfn );
|
||||
extern int pci_find_driver ( struct pci_device *pci );
|
||||
extern int pci_probe ( struct pci_device *pci );
|
||||
extern void pci_remove ( struct pci_device *pci );
|
||||
|
Loading…
Reference in New Issue
Block a user