iPXE
Functions | Variables
pci.c File Reference

PCI bus. More...

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ipxe/tables.h>
#include <ipxe/device.h>
#include <ipxe/pci.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 FILE_SECBOOT (PERMITTED)
 
static void pcibus_remove (struct root_device *rootdev)
 Remove PCI root bus. More...
 
static unsigned long pci_bar (struct pci_device *pci, unsigned int reg)
 Read PCI BAR. More...
 
unsigned long pci_bar_start (struct pci_device *pci, unsigned int reg)
 Find the start of a PCI BAR. More...
 
void pci_bar_set (struct pci_device *pci, unsigned int reg, unsigned long start)
 Set the start of a PCI BAR. More...
 
unsigned long pci_bar_size (struct pci_device *pci, unsigned int reg)
 Get the size of a PCI BAR. More...
 
static void pci_read_bases (struct pci_device *pci)
 Read membase and ioaddr for a PCI device. More...
 
void adjust_pci_device (struct pci_device *pci)
 Enable PCI device. More...
 
int pci_read_config (struct pci_device *pci)
 Read PCI device configuration. More...
 
int pci_find_next (struct pci_device *pci, uint32_t *busdevfn)
 Find next device on PCI bus. More...
 
int pci_find_driver (struct pci_device *pci)
 Find driver for PCI device. More...
 
int pci_probe (struct pci_device *pci)
 Probe a PCI device. More...
 
void pci_remove (struct pci_device *pci)
 Remove a PCI device. More...
 
static int pcibus_probe (struct root_device *rootdev)
 Probe PCI root bus. More...
 
 REQUIRING_SYMBOL (pcibus_probe)
 
 REQUIRE_OBJECT (config_pci)
 

Variables

static struct root_driver pci_root_driver
 PCI bus root device driver. More...
 
struct root_device pci_root_device __root_device
 PCI bus root device. More...
 

Detailed Description

PCI bus.

Definition in file pci.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ pcibus_remove()

static void pcibus_remove ( struct root_device rootdev)
static

Remove PCI root bus.

Parameters
rootdevPCI bus root device

Definition at line 505 of file pci.c.

505  {
506  struct pci_device *pci;
507  struct pci_device *tmp;
508 
509  list_for_each_entry_safe ( pci, tmp, &rootdev->dev.children,
510  dev.siblings ) {
511  pci_remove ( pci );
512  list_del ( &pci->dev.siblings );
513  free ( pci );
514  }
515 }
struct device dev
Device chain.
Definition: device.h:103
struct device dev
Generic device.
Definition: pci.h:213
unsigned long tmp
Definition: linux_pci.h:65
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:459
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
struct list_head siblings
Devices on the same bus.
Definition: device.h:85
A PCI device.
Definition: pci.h:211
void pci_remove(struct pci_device *pci)
Remove a PCI device.
Definition: pci.c:433
struct list_head children
Devices attached to this device.
Definition: device.h:87

References device::children, root_device::dev, pci_device::dev, free, list_del, list_for_each_entry_safe, pci_remove(), device::siblings, and tmp.

Referenced by pcibus_probe().

◆ pci_bar()

static unsigned long pci_bar ( struct pci_device pci,
unsigned int  reg 
)
static

Read PCI BAR.

Parameters
pciPCI device
regPCI register number
Return values
barBase address register

Reads the specified PCI base address register, including the flags portion. 64-bit BARs will be handled automatically. If the value of the 64-bit BAR exceeds the size of an unsigned long (i.e. if the high dword is non-zero on a 32-bit platform), then the value returned will be zero plus the flags for a 64-bit BAR. Unreachable 64-bit BARs are therefore returned as uninitialised 64-bit BARs.

Definition at line 61 of file pci.c.

61  {
62  uint32_t low;
63  uint32_t high;
64 
65  pci_read_config_dword ( pci, reg, &low );
68  pci_read_config_dword ( pci, reg + 4, &high );
69  if ( high ) {
70  if ( sizeof ( unsigned long ) > sizeof ( uint32_t ) ) {
71  return ( ( ( uint64_t ) high << 32 ) | low );
72  } else {
73  DBGC ( pci, PCI_FMT " unhandled 64-bit BAR "
74  "%08x%08x\n",
75  PCI_ARGS ( pci ), high, low );
77  }
78  }
79  }
80  return low;
81 }
uint32_t low
Low 16 bits of address.
Definition: myson.h:19
static unsigned int unsigned int reg
Definition: myson.h:162
#define DBGC(...)
Definition: compiler.h:505
unsigned long long uint64_t
Definition: stdint.h:13
int pci_read_config_dword(struct pci_device *pci, unsigned int where, uint32_t *value)
Read 32-bit dword from PCI configuration space.
uint32_t high
High 32 bits of address.
Definition: myson.h:20
#define PCI_BASE_ADDRESS_MEM_TYPE_64
64-bit memory
Definition: pci.h:71
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:312
#define PCI_BASE_ADDRESS_MEM_TYPE_MASK
Memory type mask.
Definition: pci.h:72
unsigned int uint32_t
Definition: stdint.h:12
#define PCI_BASE_ADDRESS_SPACE_IO
I/O BAR.
Definition: pci.h:69
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:315

References DBGC, high, low, PCI_ARGS, PCI_BASE_ADDRESS_MEM_TYPE_64, PCI_BASE_ADDRESS_MEM_TYPE_MASK, PCI_BASE_ADDRESS_SPACE_IO, PCI_FMT, pci_read_config_dword(), and reg.

Referenced by pci_bar_start(), and pci_read_bases().

◆ pci_bar_start()

unsigned long pci_bar_start ( struct pci_device pci,
unsigned int  reg 
)

Find the start of a PCI BAR.

Parameters
pciPCI device
regPCI register number
Return values
startBAR start address

Reads the specified PCI base address register, and returns the address portion of the BAR (i.e. without the flags).

If the address exceeds the size of an unsigned long (i.e. if a 64-bit BAR has a non-zero high dword on a 32-bit machine), the return value will be zero.

Definition at line 97 of file pci.c.

97  {
98  unsigned long bar;
99 
100  bar = pci_bar ( pci, reg );
101  if ( bar & PCI_BASE_ADDRESS_SPACE_IO ) {
102  return ( bar & ~PCI_BASE_ADDRESS_IO_MASK );
103  } else {
104  return ( bar & ~PCI_BASE_ADDRESS_MEM_MASK );
105  }
106 }
static unsigned int unsigned int reg
Definition: myson.h:162
#define PCI_BASE_ADDRESS_IO_MASK
I/O BAR mask.
Definition: pci.h:70
#define PCI_BASE_ADDRESS_MEM_MASK
Memory BAR mask.
Definition: pci.h:73
#define PCI_BASE_ADDRESS_SPACE_IO
I/O BAR.
Definition: pci.h:69
static unsigned long pci_bar(struct pci_device *pci, unsigned int reg)
Read PCI BAR.
Definition: pci.c:61

References pci_bar(), PCI_BASE_ADDRESS_IO_MASK, PCI_BASE_ADDRESS_MEM_MASK, PCI_BASE_ADDRESS_SPACE_IO, and reg.

Referenced by amd8111e_probe(), arbel_probe(), bnx2_init_board(), bnxt_pci_base(), dmfe_probe(), efab_probe(), efx_probe(), ehci_probe(), ena_membases(), exanic_probe(), flexboot_nodnic_alloc_uar(), forcedeth_map_regs(), golan_alloc_uar(), golan_pci_init(), gve_probe(), hermon_bofm_probe(), hermon_probe(), hvm_probe(), igbvf_probe(), mlx_pci_init_priv(), pci_bar_size(), pci_msix_ioremap(), phantom_map_crb(), skge_probe(), sky2_probe(), tg3_init_one(), undipci_find_rom(), virtio_pci_map_capability(), vmxnet3_probe(), vxge_probe(), and xhci_probe().

◆ pci_bar_set()

void pci_bar_set ( struct pci_device pci,
unsigned int  reg,
unsigned long  start 
)

Set the start of a PCI BAR.

Parameters
pciPCI device
regPCI register number
startBAR start address

Definition at line 115 of file pci.c.

116  {
117  unsigned int type;
118  uint32_t low;
119  uint32_t high;
120  uint16_t cmd;
121 
122  /* Save the original command register and disable decoding */
125  ( cmd & ~( PCI_COMMAND_MEM |
126  PCI_COMMAND_IO ) ) );
127 
128  /* Check for a 64-bit BAR */
129  pci_read_config_dword ( pci, reg, &low );
132 
133  /* Write low 32 bits */
134  low = start;
135  pci_write_config_dword ( pci, reg, low );
136 
137  /* Write high 32 bits, if applicable */
139  if ( sizeof ( unsigned long ) > sizeof ( uint32_t ) ) {
140  high = ( ( ( uint64_t ) start ) >> 32 );
141  } else {
142  high = 0;
143  }
144  pci_write_config_dword ( pci, reg + 4, high );
145  }
146 
147  /* Restore the original command register */
149 }
unsigned short uint16_t
Definition: stdint.h:11
uint32_t low
Low 16 bits of address.
Definition: myson.h:19
static unsigned int unsigned int reg
Definition: myson.h:162
uint32_t type
Operating system type.
Definition: ena.h:12
int pci_write_config_word(struct pci_device *pci, unsigned int where, uint16_t value)
Write 16-bit word to PCI configuration space.
unsigned long long uint64_t
Definition: stdint.h:13
int pci_read_config_word(struct pci_device *pci, unsigned int where, uint16_t *value)
Read 16-bit word from PCI configuration space.
#define PCI_COMMAND
PCI command.
Definition: pci.h:26
uint32_t start
Starting offset.
Definition: netvsc.h:12
#define PCI_COMMAND_IO
I/O space.
Definition: pci.h:27
int pci_read_config_dword(struct pci_device *pci, unsigned int where, uint32_t *value)
Read 32-bit dword from PCI configuration space.
uint32_t high
High 32 bits of address.
Definition: myson.h:20
#define PCI_BASE_ADDRESS_MEM_TYPE_64
64-bit memory
Definition: pci.h:71
#define PCI_BASE_ADDRESS_MEM_TYPE_MASK
Memory type mask.
Definition: pci.h:72
unsigned int uint32_t
Definition: stdint.h:12
#define PCI_BASE_ADDRESS_SPACE_IO
I/O BAR.
Definition: pci.h:69
int pci_write_config_dword(struct pci_device *pci, unsigned int where, uint32_t value)
Write 32-bit dword to PCI configuration space.
#define PCI_COMMAND_MEM
Memory space.
Definition: pci.h:28
struct golan_eqe_cmd cmd
Definition: CIB_PRM.h:29

References cmd, high, low, PCI_BASE_ADDRESS_MEM_TYPE_64, PCI_BASE_ADDRESS_MEM_TYPE_MASK, PCI_BASE_ADDRESS_SPACE_IO, PCI_COMMAND, PCI_COMMAND_IO, PCI_COMMAND_MEM, pci_read_config_dword(), pci_read_config_word(), pci_write_config_dword(), pci_write_config_word(), reg, start, and type.

Referenced by ena_membases(), and pci_bar_size().

◆ pci_bar_size()

unsigned long pci_bar_size ( struct pci_device pci,
unsigned int  reg 
)

Get the size of a PCI BAR.

Parameters
pciPCI device
regPCI register number
Return values
sizeBAR size

Most drivers should not need to call this function. It is not necessary to map the whole PCI BAR, only the portion that will be used for register access. Since register offsets are almost always fixed by hardware design, the length of the mapped portion will almost always be a compile-time constant.

Definition at line 164 of file pci.c.

164  {
165  unsigned long start;
166  unsigned long size;
167  uint16_t cmd;
168 
169  /* Save the original command register and disable decoding */
172  ( cmd & ~( PCI_COMMAND_MEM |
173  PCI_COMMAND_IO ) ) );
174 
175  /* Save the original start address */
176  start = pci_bar_start ( pci, reg );
177 
178  /* Set all possible bits */
179  pci_bar_set ( pci, reg, -1UL );
180 
181  /* Determine size by finding lowest set bit */
182  size = pci_bar_start ( pci, reg );
183  size &= ( -size );
184 
185  /* Restore the original start address */
186  pci_bar_set ( pci, reg, start );
187 
188  /* Restore the original command register */
190 
191  return size;
192 }
unsigned short uint16_t
Definition: stdint.h:11
static unsigned int unsigned int reg
Definition: myson.h:162
int pci_write_config_word(struct pci_device *pci, unsigned int where, uint16_t value)
Write 16-bit word to PCI configuration space.
uint16_t size
Buffer size.
Definition: dwmac.h:14
int pci_read_config_word(struct pci_device *pci, unsigned int where, uint16_t *value)
Read 16-bit word from PCI configuration space.
#define PCI_COMMAND
PCI command.
Definition: pci.h:26
void pci_bar_set(struct pci_device *pci, unsigned int reg, unsigned long start)
Set the start of a PCI BAR.
Definition: pci.c:115
uint32_t start
Starting offset.
Definition: netvsc.h:12
#define PCI_COMMAND_IO
I/O space.
Definition: pci.h:27
unsigned long pci_bar_start(struct pci_device *pci, unsigned int reg)
Find the start of a PCI BAR.
Definition: pci.c:97
#define PCI_COMMAND_MEM
Memory space.
Definition: pci.h:28
struct golan_eqe_cmd cmd
Definition: CIB_PRM.h:29

References cmd, pci_bar_set(), pci_bar_start(), PCI_COMMAND, PCI_COMMAND_IO, PCI_COMMAND_MEM, pci_read_config_word(), pci_write_config_word(), reg, size, and start.

Referenced by __vxge_hw_device_get_legacy_reg(), amd8111e_probe(), bnxt_pci_base(), efab_probe(), efx_probe(), ehci_probe(), ena_membases(), exanic_probe(), forcedeth_map_regs(), gve_probe(), hvm_probe(), igbvf_probe(), phantom_map_crb(), tg3_init_one(), virtio_pci_map_capability(), vxge_probe(), and xhci_probe().

◆ pci_read_bases()

static void pci_read_bases ( struct pci_device pci)
static

Read membase and ioaddr for a PCI device.

Parameters
pciPCI device

This scans through all PCI BARs on the specified device. The first valid memory BAR is recorded as pci_device::membase, and the first valid IO BAR is recorded as pci_device::ioaddr.

64-bit BARs are handled automatically. On a 32-bit platform, if a 64-bit BAR has a non-zero high dword, it will be regarded as invalid.

Definition at line 207 of file pci.c.

207  {
208  unsigned long bar;
209  int reg;
210 
211  /* Clear any existing base addresses */
212  pci->ioaddr = 0;
213  pci->membase = 0;
214 
215  /* Get first memory and I/O BAR addresses */
216  for ( reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4 ) {
217  bar = pci_bar ( pci, reg );
218  if ( bar & PCI_BASE_ADDRESS_SPACE_IO ) {
219  if ( ! pci->ioaddr )
220  pci->ioaddr =
221  ( bar & ~PCI_BASE_ADDRESS_IO_MASK );
222  } else {
223  if ( ! pci->membase )
224  pci->membase =
225  ( bar & ~PCI_BASE_ADDRESS_MEM_MASK );
226  /* Skip next BAR if 64-bit */
227  if ( bar & PCI_BASE_ADDRESS_MEM_TYPE_64 )
228  reg += 4;
229  }
230  }
231 }
unsigned long membase
Memory base.
Definition: pci.h:220
static unsigned int unsigned int reg
Definition: myson.h:162
unsigned long ioaddr
I/O address.
Definition: pci.h:226
#define PCI_BASE_ADDRESS_0
Definition: pci.h:63
#define PCI_BASE_ADDRESS_5
Definition: pci.h:68
#define PCI_BASE_ADDRESS_IO_MASK
I/O BAR mask.
Definition: pci.h:70
#define PCI_BASE_ADDRESS_MEM_MASK
Memory BAR mask.
Definition: pci.h:73
#define PCI_BASE_ADDRESS_MEM_TYPE_64
64-bit memory
Definition: pci.h:71
#define PCI_BASE_ADDRESS_SPACE_IO
I/O BAR.
Definition: pci.h:69
static unsigned long pci_bar(struct pci_device *pci, unsigned int reg)
Read PCI BAR.
Definition: pci.c:61

References pci_device::ioaddr, pci_device::membase, pci_bar(), PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_5, PCI_BASE_ADDRESS_IO_MASK, PCI_BASE_ADDRESS_MEM_MASK, PCI_BASE_ADDRESS_MEM_TYPE_64, PCI_BASE_ADDRESS_SPACE_IO, and reg.

Referenced by pci_read_config().

◆ adjust_pci_device()

void adjust_pci_device ( struct pci_device pci)

Enable PCI device.

Parameters
pciPCI device

Set device to be a busmaster in case BIOS neglected to do so. Also adjust PCI latency timer to a reasonable value, 32.

Definition at line 241 of file pci.c.

241  {
242  unsigned short new_command, pci_command;
243  unsigned char pci_latency;
244 
245  pci_read_config_word ( pci, PCI_COMMAND, &pci_command );
246  new_command = ( pci_command | PCI_COMMAND_MASTER |
248  if ( pci_command != new_command ) {
249  DBGC ( pci, PCI_FMT " device not enabled by BIOS! Updating "
250  "PCI command %04x->%04x\n",
251  PCI_ARGS ( pci ), pci_command, new_command );
252  pci_write_config_word ( pci, PCI_COMMAND, new_command );
253  }
254 
255  pci_read_config_byte ( pci, PCI_LATENCY_TIMER, &pci_latency);
256  if ( pci_latency < 32 ) {
257  DBGC ( pci, PCI_FMT " latency timer is unreasonably low at "
258  "%d. Setting to 32.\n", PCI_ARGS ( pci ), pci_latency );
260  }
261 }
#define PCI_LATENCY_TIMER
PCI latency timer.
Definition: pci.h:51
int pci_write_config_word(struct pci_device *pci, unsigned int where, uint16_t value)
Write 16-bit word to PCI configuration space.
#define DBGC(...)
Definition: compiler.h:505
int pci_read_config_word(struct pci_device *pci, unsigned int where, uint16_t *value)
Read 16-bit word from PCI configuration space.
#define PCI_COMMAND
PCI command.
Definition: pci.h:26
#define PCI_COMMAND_MASTER
Bus master.
Definition: pci.h:29
#define PCI_COMMAND_IO
I/O space.
Definition: pci.h:27
int pci_write_config_byte(struct pci_device *pci, unsigned int where, uint8_t value)
Write byte to PCI configuration space.
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:312
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:315
#define PCI_COMMAND_MEM
Memory space.
Definition: pci.h:28
int pci_read_config_byte(struct pci_device *pci, unsigned int where, uint8_t *value)
Read byte from PCI configuration space.

References DBGC, PCI_ARGS, PCI_COMMAND, PCI_COMMAND_IO, PCI_COMMAND_MASTER, PCI_COMMAND_MEM, PCI_FMT, PCI_LATENCY_TIMER, pci_read_config_byte(), pci_read_config_word(), pci_write_config_byte(), and pci_write_config_word().

Referenced by a3c90x_probe(), amd8111e_probe(), arbel_probe(), ath5k_probe(), ath_pci_probe(), atl1e_probe(), atl_probe(), b44_probe(), bnx2_init_board(), bnxt_init_one(), dmfe_probe(), efab_probe(), efx_probe(), ehci_probe(), ena_probe(), exanic_probe(), forcedeth_probe(), golan_pci_init(), gve_probe(), hermon_bofm_probe(), hermon_probe(), hvm_probe(), ice_probe(), icplus_probe(), ifec_pci_probe(), igbvf_probe(), intel_probe(), intelx_probe(), intelxl_probe(), intelxlvf_probe(), intelxvf_probe(), jme_probe(), linda_probe(), mlx_pci_init_priv(), myri10ge_pci_probe(), myson_probe(), natsemi_probe(), pcnet32_probe(), phantom_probe(), pnic_probe(), qib7322_probe(), rdc_probe(), realtek_probe(), rhine_probe(), rtl818x_probe(), sis190_init_board(), sis900_probe(), skeleton_probe(), skge_probe(), sky2_probe(), sundance_probe(), tg3_init_one(), tlan_probe(), tulip_probe(), txnic_bgx_probe(), txnic_pf_probe(), uhci_probe(), velocity_probe(), virtnet_probe_legacy(), virtnet_probe_modern(), vmxnet3_probe(), vxge_probe(), w89c840_probe(), and xhci_probe().

◆ pci_read_config()

int pci_read_config ( struct pci_device pci)

Read PCI device configuration.

Parameters
pciPCI device
Return values
rcReturn status code

Definition at line 269 of file pci.c.

269  {
272  uint32_t tmp;
273 
274  /* Ignore all but the first function on non-multifunction devices */
275  if ( PCI_FUNC ( pci->busdevfn ) != 0 ) {
276  busdevfn = pci->busdevfn;
277  pci->busdevfn = PCI_FIRST_FUNC ( pci->busdevfn );
279  pci->busdevfn = busdevfn;
280  if ( ! ( hdrtype & PCI_HEADER_TYPE_MULTI ) )
281  return -ENODEV;
282  }
283 
284  /* Check for physical device presence */
286  if ( ( tmp == 0xffffffff ) || ( tmp == 0 ) )
287  return -ENODEV;
288 
289  /* Populate struct pci_device */
290  pci->vendor = ( tmp & 0xffff );
291  pci->device = ( tmp >> 16 );
293  pci->class = ( tmp >> 8 );
296  pci_read_bases ( pci );
297 
298  /* Initialise generic device component */
299  snprintf ( pci->dev.name, sizeof ( pci->dev.name ), "%04x:%02x:%02x.%x",
300  PCI_SEG ( pci->busdevfn ), PCI_BUS ( pci->busdevfn ),
301  PCI_SLOT ( pci->busdevfn ), PCI_FUNC ( pci->busdevfn ) );
302  pci->dev.desc.bus_type = BUS_TYPE_PCI;
303  pci->dev.desc.location = pci->busdevfn;
304  pci->dev.desc.vendor = pci->vendor;
305  pci->dev.desc.device = pci->device;
306  pci->dev.desc.class = pci->class;
307  pci->dev.desc.ioaddr = pci->ioaddr;
308  pci->dev.desc.irq = pci->irq;
309  INIT_LIST_HEAD ( &pci->dev.siblings );
310  INIT_LIST_HEAD ( &pci->dev.children );
311 
312  return 0;
313 }
#define PCI_FUNC(busdevfn)
Definition: pci.h:286
uint8_t irq
Interrupt number.
Definition: pci.h:234
#define PCI_BUS(busdevfn)
Definition: pci.h:284
uint32_t class
Device class.
Definition: pci.h:232
unsigned long ioaddr
I/O address.
Definition: pci.h:226
unsigned long ioaddr
I/O address.
Definition: device.h:38
#define PCI_INTERRUPT_LINE
PCI interrupt line.
Definition: pci.h:91
char name[40]
Name.
Definition: device.h:79
unsigned long class
Device class.
Definition: device.h:36
unsigned int vendor
Vendor ID.
Definition: device.h:32
struct device dev
Generic device.
Definition: pci.h:213
#define PCI_HEADER_TYPE
PCI header type.
Definition: pci.h:54
unsigned long tmp
Definition: linux_pci.h:65
uint16_t busdevfn
PCI bus:dev.fn address.
Definition: ena.h:28
uint16_t device
Device ID.
Definition: pci.h:230
#define BUS_TYPE_PCI
PCI bus type.
Definition: device.h:44
static void pci_read_bases(struct pci_device *pci)
Read membase and ioaddr for a PCI device.
Definition: pci.c:207
int pci_read_config_dword(struct pci_device *pci, unsigned int where, uint32_t *value)
Read 32-bit dword from PCI configuration space.
unsigned int irq
IRQ.
Definition: device.h:40
#define PCI_FIRST_FUNC(busdevfn)
Definition: pci.h:287
unsigned int location
Location.
Definition: device.h:30
uint8_t hdrtype
Header type.
Definition: pci.h:236
#define PCI_SLOT(busdevfn)
Definition: pci.h:285
struct list_head siblings
Devices on the same bus.
Definition: device.h:85
#define ENODEV
No such device.
Definition: errno.h:510
#define PCI_VENDOR_ID
PCI vendor ID.
Definition: pci.h:20
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
uint16_t vendor
Vendor ID.
Definition: pci.h:228
uint32_t busdevfn
Segment, bus, device, and function (bus:dev.fn) number.
Definition: pci.h:238
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:46
unsigned int bus_type
Bus type.
Definition: device.h:25
unsigned int device
Device ID.
Definition: device.h:34
struct list_head children
Devices attached to this device.
Definition: device.h:87
#define PCI_REVISION
PCI revision.
Definition: pci.h:45
struct device_description desc
Device description.
Definition: device.h:83
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:383
#define PCI_SEG(busdevfn)
Definition: pci.h:283
#define PCI_HEADER_TYPE_MULTI
Multi-function device.
Definition: pci.h:59
int pci_read_config_byte(struct pci_device *pci, unsigned int where, uint8_t *value)
Read byte from PCI configuration space.

References device_description::bus_type, BUS_TYPE_PCI, busdevfn, pci_device::busdevfn, device::children, device_description::class, pci_device::class, device::desc, pci_device::dev, device_description::device, pci_device::device, ENODEV, pci_device::hdrtype, INIT_LIST_HEAD, device_description::ioaddr, pci_device::ioaddr, device_description::irq, pci_device::irq, device_description::location, device::name, PCI_BUS, PCI_FIRST_FUNC, PCI_FUNC, PCI_HEADER_TYPE, PCI_HEADER_TYPE_MULTI, PCI_INTERRUPT_LINE, pci_read_bases(), pci_read_config_byte(), pci_read_config_dword(), PCI_REVISION, PCI_SEG, PCI_SLOT, PCI_VENDOR_ID, device::siblings, snprintf(), tmp, device_description::vendor, and pci_device::vendor.

Referenced by bofm_test_init(), efipci_info(), ehci_companion(), and pci_find_next().

◆ pci_find_next()

int pci_find_next ( struct pci_device pci,
uint32_t busdevfn 
)

Find next device on PCI bus.

Parameters
pciPCI device to fill in
busdevfnStarting bus:dev.fn address
Return values
busdevfnBus:dev.fn address of next PCI device
rcReturn status code

Definition at line 323 of file pci.c.

323  {
324  static struct pci_range range;
325  uint8_t hdrtype;
326  uint8_t sub;
327  uint32_t end;
328  unsigned int count;
329  int rc;
330 
331  /* Find next PCI device, if any */
332  do {
333  /* Find next PCI bus:dev.fn address range, if necessary */
334  if ( ( *busdevfn - range.start ) >= range.count ) {
335  pci_discover ( *busdevfn, &range );
336  if ( *busdevfn < range.start )
337  *busdevfn = range.start;
338  if ( ( *busdevfn - range.start ) >= range.count )
339  break;
340  }
341 
342  /* Check for PCI device existence */
343  memset ( pci, 0, sizeof ( *pci ) );
344  pci_init ( pci, *busdevfn );
345  if ( ( rc = pci_read_config ( pci ) ) != 0 )
346  continue;
347 
348  /* If device is a bridge, expand the PCI bus:dev.fn
349  * address range as needed.
350  */
351  pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
352  hdrtype &= PCI_HEADER_TYPE_MASK;
353  if ( hdrtype == PCI_HEADER_TYPE_BRIDGE ) {
354  pci_read_config_byte ( pci, PCI_SUBORDINATE, &sub );
355  end = PCI_BUSDEVFN ( PCI_SEG ( *busdevfn ),
356  ( sub + 1 ), 0, 0 );
357  count = ( end - range.start );
358  if ( count > range.count ) {
359  DBGC ( pci, PCI_FMT " found subordinate bus "
360  "%#02x\n", PCI_ARGS ( pci ), sub );
361  range.count = count;
362  }
363  }
364 
365  /* Return this device */
366  return 0;
367 
368  } while ( ++(*busdevfn) );
369 
370  return -ENODEV;
371 }
#define PCI_HEADER_TYPE_BRIDGE
PCI-to-PCI bridge header.
Definition: pci.h:56
uint32_t start
Starting bus:dev.fn address.
Definition: pci_io.h:25
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct pci_range range
PCI bus:dev.fn address range.
Definition: pcicloud.c:40
#define PCI_HEADER_TYPE_MASK
Header type mask.
Definition: pci.h:58
#define DBGC(...)
Definition: compiler.h:505
#define PCI_HEADER_TYPE
PCI header type.
Definition: pci.h:54
uint16_t busdevfn
PCI bus:dev.fn address.
Definition: ena.h:28
A PCI bus:dev.fn address range.
Definition: pci_io.h:23
static unsigned int count
Number of entries.
Definition: dwmac.h:225
#define PCI_BUSDEVFN(segment, bus, slot, func)
Definition: pci_io.h:30
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:312
int pci_read_config(struct pci_device *pci)
Read PCI device configuration.
Definition: pci.c:269
#define ENODEV
No such device.
Definition: errno.h:510
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
unsigned int count
Number of bus:dev.fn addresses within this range.
Definition: pci_io.h:27
void pci_discover(uint32_t busdevfn, struct pci_range *range)
Find next PCI bus:dev.fn address range in system.
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:315
uint32_t end
Ending offset.
Definition: netvsc.h:18
#define PCI_SUBORDINATE
Subordinate bus number.
Definition: pci.h:150
static void pci_init(struct pci_device *pci, unsigned int busdevfn)
Initialise PCI device.
Definition: pci.h:341
#define PCI_SEG(busdevfn)
Definition: pci.h:283
void * memset(void *dest, int character, size_t len) __nonnull
int pci_read_config_byte(struct pci_device *pci, unsigned int where, uint8_t *value)
Read byte from PCI configuration space.

References busdevfn, pci_range::count, count, DBGC, end, ENODEV, memset(), PCI_ARGS, PCI_BUSDEVFN, pci_discover(), PCI_FMT, PCI_HEADER_TYPE, PCI_HEADER_TYPE_BRIDGE, PCI_HEADER_TYPE_MASK, pci_init(), pci_read_config(), pci_read_config_byte(), PCI_SEG, PCI_SUBORDINATE, range, rc, and pci_range::start.

Referenced by pcibus_probe(), and pciscan_exec().

◆ pci_find_driver()

int pci_find_driver ( struct pci_device pci)

Find driver for PCI device.

Parameters
pciPCI device
Return values
rcReturn status code

Definition at line 379 of file pci.c.

379  {
380  struct pci_driver *driver;
381  struct pci_device_id *id;
382  unsigned int i;
383 
384  for_each_table_entry ( driver, PCI_DRIVERS ) {
385  if ( ( driver->class.class ^ pci->class ) & driver->class.mask )
386  continue;
387  for ( i = 0 ; i < driver->id_count ; i++ ) {
388  id = &driver->ids[i];
389  if ( ( id->vendor != PCI_ANY_ID ) &&
390  ( id->vendor != pci->vendor ) )
391  continue;
392  if ( ( id->device != PCI_ANY_ID ) &&
393  ( id->device != pci->device ) )
394  continue;
395  pci_set_driver ( pci, driver, id );
396  return 0;
397  }
398  }
399  return -ENOENT;
400 }
struct pci_class_id class
PCI class ID.
Definition: pci.h:258
A PCI driver.
Definition: pci.h:252
uint32_t class
Device class.
Definition: pci.h:232
unsigned int id_count
Number of entries in PCI ID table.
Definition: pci.h:256
struct pci_device_id * ids
PCI ID table.
Definition: pci.h:254
static void pci_set_driver(struct pci_device *pci, struct pci_driver *driver, struct pci_device_id *id)
Set PCI driver.
Definition: pci.h:352
#define ENOENT
No such file or directory.
Definition: errno.h:515
uint32_t mask
Class mask.
Definition: pci.h:194
uint32_t class
Class.
Definition: pci.h:192
uint16_t device
Device ID.
Definition: pci.h:230
uint8_t id
Request identifier.
Definition: ena.h:12
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:386
A PCI device ID list entry.
Definition: pci.h:175
uint16_t vendor
Vendor ID.
Definition: pci.h:228
#define PCI_ANY_ID
Match-anything ID.
Definition: pci.h:187
#define PCI_DRIVERS
PCI driver table.
Definition: pci.h:275

References pci_class_id::class, pci_device::class, pci_driver::class, pci_device::device, ENOENT, for_each_table_entry, id, pci_driver::id_count, pci_driver::ids, pci_class_id::mask, PCI_ANY_ID, PCI_DRIVERS, pci_set_driver(), and pci_device::vendor.

Referenced by efipci_start(), efipci_supported(), and pcibus_probe().

◆ pci_probe()

int pci_probe ( struct pci_device pci)

Probe a PCI device.

Parameters
pciPCI device
Return values
rcReturn status code

Searches for a driver for the PCI device. If a driver is found, its probe() routine is called.

Definition at line 411 of file pci.c.

411  {
412  int rc;
413 
414  DBGC ( pci, PCI_FMT " (%04x:%04x) has driver \"%s\"\n",
415  PCI_ARGS ( pci ), pci->vendor, pci->device, pci->id->name );
416  DBGC ( pci, PCI_FMT " has mem %lx io %lx irq %d\n",
417  PCI_ARGS ( pci ), pci->membase, pci->ioaddr, pci->irq );
418 
419  if ( ( rc = pci->driver->probe ( pci ) ) != 0 ) {
420  DBGC ( pci, PCI_FMT " probe failed: %s\n",
421  PCI_ARGS ( pci ), strerror ( rc ) );
422  return rc;
423  }
424 
425  return 0;
426 }
unsigned long membase
Memory base.
Definition: pci.h:220
uint8_t irq
Interrupt number.
Definition: pci.h:234
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct pci_driver * driver
Driver for this device.
Definition: pci.h:240
unsigned long ioaddr
I/O address.
Definition: pci.h:226
#define DBGC(...)
Definition: compiler.h:505
uint16_t device
Device ID.
Definition: pci.h:230
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:312
const char * name
Name.
Definition: pci.h:177
uint16_t vendor
Vendor ID.
Definition: pci.h:228
int(* probe)(struct pci_device *pci)
Probe device.
Definition: pci.h:265
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:315
struct pci_device_id * id
Driver device ID.
Definition: pci.h:248

References DBGC, pci_device::device, pci_device::driver, pci_device::id, pci_device::ioaddr, pci_device::irq, pci_device::membase, pci_device_id::name, PCI_ARGS, PCI_FMT, pci_driver::probe, rc, strerror(), and pci_device::vendor.

Referenced by bofm_probe(), efipci_start(), and pcibus_probe().

◆ pci_remove()

void pci_remove ( struct pci_device pci)

Remove a PCI device.

Parameters
pciPCI device

Definition at line 433 of file pci.c.

433  {
434  pci->driver->remove ( pci );
435  DBGC ( pci, PCI_FMT " removed\n", PCI_ARGS ( pci ) );
436 }
struct pci_driver * driver
Driver for this device.
Definition: pci.h:240
void(* remove)(struct pci_device *pci)
Remove device.
Definition: pci.h:271
#define DBGC(...)
Definition: compiler.h:505
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:312
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:315

References DBGC, pci_device::driver, PCI_ARGS, PCI_FMT, and pci_driver::remove.

Referenced by bofm_remove(), efipci_start(), efipci_stop(), and pcibus_remove().

◆ pcibus_probe()

static int pcibus_probe ( struct root_device rootdev)
static

Probe PCI root bus.

Parameters
rootdevPCI bus root device

Scans the PCI bus for devices and registers all devices it can find.

Definition at line 446 of file pci.c.

446  {
447  struct pci_device *pci = NULL;
448  uint32_t busdevfn = 0;
449  int rc;
450 
451  do {
452  /* Allocate struct pci_device */
453  if ( ! pci )
454  pci = malloc ( sizeof ( *pci ) );
455  if ( ! pci ) {
456  rc = -ENOMEM;
457  goto err;
458  }
459 
460  /* Find next PCI device, if any */
461  if ( ( rc = pci_find_next ( pci, &busdevfn ) ) != 0 )
462  break;
463 
464  /* Skip automatic probing if prohibited */
465  if ( ! pci_can_probe ( pci ) )
466  continue;
467 
468  /* Look for a driver */
469  if ( ( rc = pci_find_driver ( pci ) ) != 0 ) {
470  DBGC ( pci, PCI_FMT " (%04x:%04x class %06x) has no "
471  "driver\n", PCI_ARGS ( pci ), pci->vendor,
472  pci->device, pci->class );
473  continue;
474  }
475 
476  /* Add to device hierarchy */
477  pci->dev.parent = &rootdev->dev;
478  list_add ( &pci->dev.siblings, &rootdev->dev.children );
479 
480  /* Look for a driver */
481  if ( ( rc = pci_probe ( pci ) ) == 0 ) {
482  /* pcidev registered, we can drop our ref */
483  pci = NULL;
484  } else {
485  /* Not registered; re-use struct pci_device */
486  list_del ( &pci->dev.siblings );
487  }
488 
489  } while ( ++busdevfn );
490 
491  free ( pci );
492  return 0;
493 
494  err:
495  free ( pci );
496  pcibus_remove ( rootdev );
497  return rc;
498 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int pci_find_driver(struct pci_device *pci)
Find driver for PCI device.
Definition: pci.c:379
uint32_t class
Device class.
Definition: pci.h:232
int pci_can_probe(struct pci_device *pci)
Check if PCI bus probing is allowed.
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:70
#define DBGC(...)
Definition: compiler.h:505
struct device dev
Device chain.
Definition: device.h:103
struct device * parent
Bus device.
Definition: device.h:89
struct device dev
Generic device.
Definition: pci.h:213
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
uint16_t busdevfn
PCI bus:dev.fn address.
Definition: ena.h:28
#define ENOMEM
Not enough space.
Definition: errno.h:535
int pci_find_next(struct pci_device *pci, uint32_t *busdevfn)
Find next device on PCI bus.
Definition: pci.c:323
uint16_t device
Device ID.
Definition: pci.h:230
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:312
struct list_head siblings
Devices on the same bus.
Definition: device.h:85
A PCI device.
Definition: pci.h:211
unsigned int uint32_t
Definition: stdint.h:12
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:621
uint16_t vendor
Vendor ID.
Definition: pci.h:228
static void pcibus_remove(struct root_device *rootdev)
Remove PCI root bus.
Definition: pci.c:505
struct list_head children
Devices attached to this device.
Definition: device.h:87
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:315
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
int pci_probe(struct pci_device *pci)
Probe a PCI device.
Definition: pci.c:411

References busdevfn, device::children, pci_device::class, DBGC, root_device::dev, pci_device::dev, pci_device::device, ENOMEM, free, list_add, list_del, malloc(), NULL, device::parent, PCI_ARGS, pci_can_probe(), pci_find_driver(), pci_find_next(), PCI_FMT, pci_probe(), pcibus_remove(), rc, device::siblings, and pci_device::vendor.

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( pcibus_probe  )

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( config_pci  )

Variable Documentation

◆ pci_root_driver

struct root_driver pci_root_driver
static
Initial value:
= {
.probe = pcibus_probe,
.remove = pcibus_remove,
}
static int pcibus_probe(struct root_device *rootdev)
Probe PCI root bus.
Definition: pci.c:446
static void pcibus_remove(struct root_device *rootdev)
Remove PCI root bus.
Definition: pci.c:505

PCI bus root device driver.

Definition at line 518 of file pci.c.

◆ __root_device

struct root_device pci_root_device __root_device
Initial value:
= {
.dev = { .name = "PCI" },
.driver = &pci_root_driver,
}
static struct root_driver pci_root_driver
PCI bus root device driver.
Definition: pci.c:518

PCI bus root device.

Definition at line 524 of file pci.c.