diff --git a/src/arch/i386/drivers/net/undi.c b/src/arch/i386/drivers/net/undi.c index 71d8453a4..017843f6a 100644 --- a/src/arch/i386/drivers/net/undi.c +++ b/src/arch/i386/drivers/net/undi.c @@ -66,7 +66,6 @@ static int undipci_probe ( struct pci_device *pci, const struct pci_device_id *id __unused ) { struct undi_device *undi; struct undi_rom *undirom; - unsigned int busdevfn = PCI_BUSDEVFN ( pci->bus, pci->devfn ); int rc; /* Ignore non-network devices */ @@ -80,7 +79,7 @@ static int undipci_probe ( struct pci_device *pci, pci_set_drvdata ( pci, undi ); /* Find/create our pixie */ - if ( preloaded_undi.pci_busdevfn == busdevfn ) { + if ( preloaded_undi.pci_busdevfn == pci->busdevfn ) { /* Claim preloaded UNDI device */ DBGC ( undi, "UNDI %p using preloaded UNDI device\n", undi ); memcpy ( undi, &preloaded_undi, sizeof ( *undi ) ); @@ -93,8 +92,10 @@ static int undipci_probe ( struct pci_device *pci, } /* Call UNDI ROM loader to create pixie */ - if ( ( rc = undi_load_pci ( undi, undirom, busdevfn ) ) != 0 ) + if ( ( rc = undi_load_pci ( undi, undirom, + pci->busdevfn ) ) != 0 ) { goto err_load_pci; + } } /* Add to device hierarchy */ diff --git a/src/arch/i386/interface/pcbios/pcibios.c b/src/arch/i386/interface/pcbios/pcibios.c index 4d09c054e..9f69fe6e4 100644 --- a/src/arch/i386/interface/pcbios/pcibios.c +++ b/src/arch/i386/interface/pcbios/pcibios.c @@ -73,7 +73,7 @@ int pcibios_read ( struct pci_device *pci, uint32_t command, uint32_t *value ){ : "=a" ( status ), "=b" ( discard_b ), "=c" ( *value ), "=D" ( discard_D ) : "a" ( command >> 16 ), "D" ( command ), - "b" ( PCI_BUSDEVFN ( pci->bus, pci->devfn ) ) + "b" ( pci->busdevfn ) : "edx" ); return ( ( status >> 8 ) & 0xff ); @@ -99,8 +99,7 @@ int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ){ : "=a" ( status ), "=b" ( discard_b ), "=c" ( discard_c ), "=D" ( discard_D ) : "a" ( command >> 16 ), "D" ( command ), - "b" ( PCI_BUSDEVFN ( pci->bus, pci->devfn ) ), - "c" ( value ) + "b" ( pci->busdevfn ), "c" ( value ) : "edx" ); return ( ( status >> 8 ) & 0xff ); diff --git a/src/arch/x86/core/pcidirect.c b/src/arch/x86/core/pcidirect.c index 38e056d57..ae74b7f15 100644 --- a/src/arch/x86/core/pcidirect.c +++ b/src/arch/x86/core/pcidirect.c @@ -34,8 +34,8 @@ FILE_LICENCE ( GPL2_OR_LATER ); * @v where Location within PCI configuration space */ void pcidirect_prepare ( struct pci_device *pci, int where ) { - outl ( ( 0x80000000 | ( pci->bus << 16 ) | ( pci->devfn << 8 ) | - ( where & ~3 ) ), PCIDIRECT_CONFIG_ADDRESS ); + outl ( ( 0x80000000 | ( pci->busdevfn << 8 ) | ( where & ~3 ) ), + PCIDIRECT_CONFIG_ADDRESS ); } PROVIDE_PCIAPI_INLINE ( direct, pci_max_bus ); diff --git a/src/drivers/bus/pci.c b/src/drivers/bus/pci.c index 3ff544401..e92f11b2f 100644 --- a/src/drivers/bus/pci.c +++ b/src/drivers/bus/pci.c @@ -228,75 +228,72 @@ static void pci_remove ( struct pci_device *pci ) { */ static int pcibus_probe ( struct root_device *rootdev ) { struct pci_device *pci = NULL; - unsigned int max_bus; - unsigned int bus; - unsigned int devfn; + unsigned int num_bus; + unsigned int busdevfn; uint8_t hdrtype = 0; uint32_t tmp; int rc; - max_bus = pci_max_bus(); - for ( bus = 0 ; bus <= max_bus ; bus++ ) { - for ( devfn = 0 ; devfn <= 0xff ; devfn++ ) { + num_bus = ( pci_max_bus() + 1 ); + for ( busdevfn = 0 ; busdevfn < PCI_BUSDEVFN ( num_bus, 0, 0 ) ; + busdevfn++ ) { - /* Allocate struct pci_device */ - if ( ! pci ) - pci = malloc ( sizeof ( *pci ) ); - if ( ! pci ) { - rc = -ENOMEM; - goto err; - } - memset ( pci, 0, sizeof ( *pci ) ); - pci->bus = bus; - pci->devfn = devfn; + /* Allocate struct pci_device */ + if ( ! pci ) + pci = malloc ( sizeof ( *pci ) ); + if ( ! pci ) { + rc = -ENOMEM; + goto err; + } + memset ( pci, 0, sizeof ( *pci ) ); + pci->busdevfn = busdevfn; - /* Skip all but the first function on - * non-multifunction cards - */ - if ( PCI_FUNC ( devfn ) == 0 ) { - pci_read_config_byte ( pci, PCI_HEADER_TYPE, - &hdrtype ); - } else if ( ! ( hdrtype & 0x80 ) ) { - continue; - } + /* 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; + } - /* Check for physical device presence */ - pci_read_config_dword ( pci, PCI_VENDOR_ID, &tmp ); - if ( ( tmp == 0xffffffff ) || ( tmp == 0 ) ) - continue; + /* Check for physical device presence */ + pci_read_config_dword ( pci, PCI_VENDOR_ID, &tmp ); + if ( ( tmp == 0xffffffff ) || ( tmp == 0 ) ) + continue; - /* Populate struct pci_device */ - pci->vendor = ( tmp & 0xffff ); - pci->device = ( tmp >> 16 ); - pci_read_config_dword ( pci, PCI_REVISION, &tmp ); - pci->class = ( tmp >> 8 ); - pci_read_config_byte ( pci, PCI_INTERRUPT_LINE, - &pci->irq ); - pci_read_bases ( pci ); + /* Populate struct pci_device */ + pci->vendor = ( tmp & 0xffff ); + pci->device = ( tmp >> 16 ); + pci_read_config_dword ( pci, PCI_REVISION, &tmp ); + pci->class = ( tmp >> 8 ); + pci_read_config_byte ( pci, PCI_INTERRUPT_LINE, + &pci->irq ); + pci_read_bases ( pci ); - /* Add to device hierarchy */ - snprintf ( pci->dev.name, sizeof ( pci->dev.name ), - "PCI%02x:%02x.%x", bus, - PCI_SLOT ( devfn ), PCI_FUNC ( devfn ) ); - pci->dev.desc.bus_type = BUS_TYPE_PCI; - pci->dev.desc.location = PCI_BUSDEVFN (bus, devfn); - pci->dev.desc.vendor = pci->vendor; - pci->dev.desc.device = pci->device; - pci->dev.desc.class = pci->class; - pci->dev.desc.ioaddr = pci->ioaddr; - pci->dev.desc.irq = pci->irq; - pci->dev.parent = &rootdev->dev; - list_add ( &pci->dev.siblings, &rootdev->dev.children); - INIT_LIST_HEAD ( &pci->dev.children ); - - /* Look for a driver */ - if ( pci_probe ( pci ) == 0 ) { - /* pcidev registered, we can drop our ref */ - pci = NULL; - } else { - /* Not registered; re-use struct pci_device */ - list_del ( &pci->dev.siblings ); - } + /* Add to device hierarchy */ + snprintf ( pci->dev.name, sizeof ( pci->dev.name ), + "PCI%02x:%02x.%x", PCI_BUS ( busdevfn ), + PCI_SLOT ( busdevfn ), PCI_FUNC ( busdevfn ) ); + pci->dev.desc.bus_type = BUS_TYPE_PCI; + pci->dev.desc.location = pci->busdevfn; + pci->dev.desc.vendor = pci->vendor; + pci->dev.desc.device = pci->device; + pci->dev.desc.class = pci->class; + pci->dev.desc.ioaddr = pci->ioaddr; + pci->dev.desc.irq = pci->irq; + pci->dev.parent = &rootdev->dev; + list_add ( &pci->dev.siblings, &rootdev->dev.children); + INIT_LIST_HEAD ( &pci->dev.children ); + + /* Look for a driver */ + if ( pci_probe ( pci ) == 0 ) { + /* pcidev registered, we can drop our ref */ + pci = NULL; + } else { + /* Not registered; re-use struct pci_device */ + list_del ( &pci->dev.siblings ); } } diff --git a/src/drivers/net/phantom/phantom.c b/src/drivers/net/phantom/phantom.c index f6b2f0064..6a3f5f7bf 100644 --- a/src/drivers/net/phantom/phantom.c +++ b/src/drivers/net/phantom/phantom.c @@ -1792,9 +1792,8 @@ static int phantom_map_crb ( struct phantom_nic *phantom, bar0_start = pci_bar_start ( pci, PCI_BASE_ADDRESS_0 ); bar0_size = pci_bar_size ( pci, PCI_BASE_ADDRESS_0 ); - DBGC ( phantom, "Phantom %p is PCI %02x:%02x.%x with BAR0 at " - "%08lx+%lx\n", phantom, pci->bus, PCI_SLOT ( pci->devfn ), - PCI_FUNC ( pci->devfn ), bar0_start, bar0_size ); + DBGC ( phantom, "Phantom %p is " PCI_FMT " with BAR0 at %08lx+%lx\n", + phantom, PCI_ARGS ( pci ), bar0_start, bar0_size ); if ( ! bar0_start ) { DBGC ( phantom, "Phantom %p BAR not assigned; ignoring\n", @@ -2057,7 +2056,7 @@ static int phantom_probe ( struct pci_device *pci, pci_set_drvdata ( pci, netdev ); netdev->dev = &pci->dev; memset ( phantom, 0, sizeof ( *phantom ) ); - phantom->port = PCI_FUNC ( pci->devfn ); + phantom->port = PCI_FUNC ( pci->busdevfn ); assert ( phantom->port < PHN_MAX_NUM_PORTS ); settings_init ( &phantom->settings, &phantom_settings_operations, @@ -2074,16 +2073,19 @@ static int phantom_probe ( struct pci_device *pci, * B2 will have this fixed; remove this hack when B1 is no * longer in use. */ - if ( PCI_FUNC ( pci->devfn ) == 0 ) { + if ( PCI_FUNC ( pci->busdevfn ) == 0 ) { unsigned int i; for ( i = 0 ; i < 8 ; i++ ) { uint32_t temp; - pci->devfn = PCI_DEVFN ( PCI_SLOT ( pci->devfn ), i ); + pci->busdevfn = + PCI_BUSDEVFN ( PCI_BUS ( pci->busdevfn ), + PCI_SLOT ( pci->busdevfn ), i ); pci_read_config_dword ( pci, 0xc8, &temp ); pci_read_config_dword ( pci, 0xc8, &temp ); pci_write_config_dword ( pci, 0xc8, 0xf1000 ); } - pci->devfn = PCI_DEVFN ( PCI_SLOT ( pci->devfn ), 0 ); + pci->busdevfn = PCI_BUSDEVFN ( PCI_BUS ( pci->busdevfn ), + PCI_SLOT ( pci->busdevfn ), 0 ); } /* Initialise the command PEG */ diff --git a/src/drivers/net/tg3.c b/src/drivers/net/tg3.c index 4ff72ace6..e1562d4c8 100644 --- a/src/drivers/net/tg3.c +++ b/src/drivers/net/tg3.c @@ -2909,7 +2909,7 @@ static int tg3_get_device_address(struct tg3 *tp) struct nic *nic = tp->nic; uint32_t hi, lo, mac_offset; - if (PCI_FUNC(tp->pdev->devfn) == 0) + if (PCI_FUNC(tp->pdev->busdevfn) == 0) mac_offset = 0x7c; else mac_offset = 0xcc; diff --git a/src/drivers/net/vxge/vxge_main.c b/src/drivers/net/vxge/vxge_main.c index e2abafbf9..a85634471 100644 --- a/src/drivers/net/vxge/vxge_main.c +++ b/src/drivers/net/vxge/vxge_main.c @@ -511,9 +511,8 @@ vxge_probe(struct pci_device *pdev, const struct pci_device_id *id __unused) struct vxge_hw_device_hw_info hw_info; struct vxge_hw_device_version *fw_version; - vxge_debug(VXGE_INFO, "vxge_probe for device %02X:%02X.%X\n", - pdev->bus, PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn)); + vxge_debug(VXGE_INFO, "vxge_probe for device " PCI_FMT "\n", + PCI_ARGS(pdev)); pci_read_config_byte(pdev, PCI_REVISION_ID, &revision); titan1 = is_titan1(pdev->device, revision); diff --git a/src/include/ipxe/pci.h b/src/include/ipxe/pci.h index 90e268985..01df76176 100644 --- a/src/include/ipxe/pci.h +++ b/src/include/ipxe/pci.h @@ -302,10 +302,8 @@ struct pci_device { uint32_t class; /** Interrupt number */ uint8_t irq; - /** Bus number */ - uint8_t bus; - /** Device and function number */ - uint8_t devfn; + /** Bus, device, and function (bus:dev.fn) number */ + uint16_t busdevfn; /** Driver for this device */ struct pci_driver *driver; /** Driver-private data @@ -347,11 +345,11 @@ struct pci_driver { /** Declare a PCI driver */ #define __pci_driver __table_entry ( PCI_DRIVERS, 01 ) -#define PCI_DEVFN( slot, func ) ( ( (slot) << 3 ) | (func) ) -#define PCI_SLOT( devfn ) ( ( (devfn) >> 3 ) & 0x1f ) -#define PCI_FUNC( devfn ) ( (devfn) & 0x07 ) -#define PCI_BUS( busdevfn ) ( (busdevfn) >> 8 ) -#define PCI_BUSDEVFN( bus, devfn ) ( ( (bus) << 8 ) | (devfn) ) +#define PCI_BUS( busdevfn ) ( ( (busdevfn) >> 8 ) & 0xff ) +#define PCI_SLOT( busdevfn ) ( ( (busdevfn) >> 3 ) & 0x1f ) +#define PCI_FUNC( busdevfn ) ( ( (busdevfn) >> 0 ) & 0x07 ) +#define PCI_BUSDEVFN( bus, slot, func ) \ + ( ( (bus) << 8 ) | ( (slot) << 3 ) | ( (func) << 0 ) ) #define PCI_BASE_CLASS( class ) ( (class) >> 16 ) #define PCI_SUB_CLASS( class ) ( ( (class) >> 8 ) & 0xff ) @@ -378,8 +376,9 @@ struct pci_driver { #define PCI_FMT "PCI %02x:%02x.%x" /** PCI device debug message arguments */ -#define PCI_ARGS( pci ) \ - (pci)->bus, PCI_SLOT ( (pci)->devfn ), PCI_FUNC ( (pci)->devfn ) +#define PCI_ARGS( pci ) \ + PCI_BUS ( (pci)->busdevfn ), PCI_SLOT ( (pci)->busdevfn ), \ + PCI_FUNC ( (pci)->busdevfn ) extern void adjust_pci_device ( struct pci_device *pci ); extern unsigned long pci_bar_start ( struct pci_device *pci, diff --git a/src/interface/efi/efi_pci.c b/src/interface/efi/efi_pci.c index 9a402c447..c240d4cb7 100644 --- a/src/interface/efi/efi_pci.c +++ b/src/interface/efi/efi_pci.c @@ -35,8 +35,9 @@ EFI_REQUIRE_PROTOCOL ( EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL, &efipci ); static unsigned long efipci_address ( struct pci_device *pci, unsigned long location ) { - return EFI_PCI_ADDRESS ( pci->bus, PCI_SLOT ( pci->devfn ), - PCI_FUNC ( pci->devfn ), + return EFI_PCI_ADDRESS ( PCI_BUS ( pci->busdevfn ), + PCI_SLOT ( pci->busdevfn ), + PCI_FUNC ( pci->busdevfn ), EFIPCI_OFFSET ( location ) ); } @@ -47,10 +48,9 @@ int efipci_read ( struct pci_device *pci, unsigned long location, if ( ( efirc = efipci->Pci.Read ( efipci, EFIPCI_WIDTH ( location ), efipci_address ( pci, location ), 1, value ) ) != 0 ) { - DBG ( "EFIPCI config read from %02x:%02x.%x offset %02lx " - "failed: %s\n", pci->bus, PCI_SLOT ( pci->devfn ), - PCI_FUNC ( pci->devfn ), EFIPCI_OFFSET ( location ), - efi_strerror ( efirc ) ); + DBG ( "EFIPCI config read from " PCI_FMT " offset %02lx " + "failed: %s\n", PCI_ARGS ( pci ), + EFIPCI_OFFSET ( location ), efi_strerror ( efirc ) ); return -EIO; } @@ -64,10 +64,9 @@ int efipci_write ( struct pci_device *pci, unsigned long location, if ( ( efirc = efipci->Pci.Write ( efipci, EFIPCI_WIDTH ( location ), efipci_address ( pci, location ), 1, &value ) ) != 0 ) { - DBG ( "EFIPCI config write to %02x:%02x.%x offset %02lx " - "failed: %s\n", pci->bus, PCI_SLOT ( pci->devfn ), - PCI_FUNC ( pci->devfn ), EFIPCI_OFFSET ( location ), - efi_strerror ( efirc ) ); + DBG ( "EFIPCI config write to " PCI_FMT " offset %02lx " + "failed: %s\n", PCI_ARGS ( pci ), + EFIPCI_OFFSET ( location ), efi_strerror ( efirc ) ); return -EIO; } diff --git a/src/interface/efi/efi_snp.c b/src/interface/efi/efi_snp.c index 43620f57e..6bfa18884 100644 --- a/src/interface/efi/efi_snp.c +++ b/src/interface/efi/efi_snp.c @@ -794,7 +794,7 @@ efi_snp_netdev ( EFI_DRIVER_BINDING_PROTOCOL *driver, EFI_HANDLE device ) { ( ( unsigned long ) pci_fn ) ); /* Look up corresponding network device */ - pci_busdevfn = PCI_BUSDEVFN ( pci_bus, PCI_DEVFN ( pci_dev, pci_fn ) ); + pci_busdevfn = PCI_BUSDEVFN ( pci_bus, pci_dev, pci_fn ); if ( ( netdev = find_netdev_by_location ( BUS_TYPE_PCI, pci_busdevfn ) ) == NULL ) { DBGCP ( driver, "SNPDRV %p device %p is not a iPXE network "