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)
 
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  )

◆ pcibus_remove()

static void pcibus_remove ( struct root_device rootdev)
static

Remove PCI root bus.

Parameters
rootdevPCI bus root device

Definition at line 504 of file pci.c.

504  {
505  struct pci_device *pci;
506  struct pci_device *tmp;
507 
508  list_for_each_entry_safe ( pci, tmp, &rootdev->dev.children,
509  dev.siblings ) {
510  pci_remove ( pci );
511  list_del ( &pci->dev.siblings );
512  free ( pci );
513  }
514 }
struct device dev
Device chain.
Definition: device.h:102
struct device dev
Generic device.
Definition: pci.h:212
unsigned long tmp
Definition: linux_pci.h:64
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#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:458
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct list_head siblings
Devices on the same bus.
Definition: device.h:84
A PCI device.
Definition: pci.h:210
void pci_remove(struct pci_device *pci)
Remove a PCI device.
Definition: pci.c:432
struct list_head children
Devices attached to this device.
Definition: device.h:86

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 60 of file pci.c.

60  {
61  uint32_t low;
62  uint32_t high;
63 
64  pci_read_config_dword ( pci, reg, &low );
67  pci_read_config_dword ( pci, reg + 4, &high );
68  if ( high ) {
69  if ( sizeof ( unsigned long ) > sizeof ( uint32_t ) ) {
70  return ( ( ( uint64_t ) high << 32 ) | low );
71  } else {
72  DBGC ( pci, PCI_FMT " unhandled 64-bit BAR "
73  "%08x%08x\n",
74  PCI_ARGS ( pci ), high, low );
76  }
77  }
78  }
79  return low;
80 }
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:70
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:311
#define PCI_BASE_ADDRESS_MEM_TYPE_MASK
Memory type mask.
Definition: pci.h:71
unsigned int uint32_t
Definition: stdint.h:12
#define PCI_BASE_ADDRESS_SPACE_IO
I/O BAR.
Definition: pci.h:68
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:314

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 96 of file pci.c.

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

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 114 of file pci.c.

115  {
116  unsigned int type;
117  uint32_t low;
118  uint32_t high;
119  uint16_t cmd;
120 
121  /* Save the original command register and disable decoding */
124  ( cmd & ~( PCI_COMMAND_MEM |
125  PCI_COMMAND_IO ) ) );
126 
127  /* Check for a 64-bit BAR */
128  pci_read_config_dword ( pci, reg, &low );
131 
132  /* Write low 32 bits */
133  low = start;
134  pci_write_config_dword ( pci, reg, low );
135 
136  /* Write high 32 bits, if applicable */
138  if ( sizeof ( unsigned long ) > sizeof ( uint32_t ) ) {
139  high = ( ( ( uint64_t ) start ) >> 32 );
140  } else {
141  high = 0;
142  }
143  pci_write_config_dword ( pci, reg + 4, high );
144  }
145 
146  /* Restore the original command register */
148 }
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:25
uint32_t start
Starting offset.
Definition: netvsc.h:12
#define PCI_COMMAND_IO
I/O space.
Definition: pci.h:26
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:70
#define PCI_BASE_ADDRESS_MEM_TYPE_MASK
Memory type mask.
Definition: pci.h:71
unsigned int uint32_t
Definition: stdint.h:12
#define PCI_BASE_ADDRESS_SPACE_IO
I/O BAR.
Definition: pci.h:68
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:27
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 163 of file pci.c.

163  {
164  unsigned long start;
165  unsigned long size;
166  uint16_t cmd;
167 
168  /* Save the original command register and disable decoding */
171  ( cmd & ~( PCI_COMMAND_MEM |
172  PCI_COMMAND_IO ) ) );
173 
174  /* Save the original start address */
175  start = pci_bar_start ( pci, reg );
176 
177  /* Set all possible bits */
178  pci_bar_set ( pci, reg, -1UL );
179 
180  /* Determine size by finding lowest set bit */
181  size = pci_bar_start ( pci, reg );
182  size &= ( -size );
183 
184  /* Restore the original start address */
185  pci_bar_set ( pci, reg, start );
186 
187  /* Restore the original command register */
189 
190  return size;
191 }
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:25
void pci_bar_set(struct pci_device *pci, unsigned int reg, unsigned long start)
Set the start of a PCI BAR.
Definition: pci.c:114
uint32_t start
Starting offset.
Definition: netvsc.h:12
#define PCI_COMMAND_IO
I/O space.
Definition: pci.h:26
unsigned long pci_bar_start(struct pci_device *pci, unsigned int reg)
Find the start of a PCI BAR.
Definition: pci.c:96
#define PCI_COMMAND_MEM
Memory space.
Definition: pci.h:27
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 206 of file pci.c.

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

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 240 of file pci.c.

240  {
241  unsigned short new_command, pci_command;
242  unsigned char pci_latency;
243 
244  pci_read_config_word ( pci, PCI_COMMAND, &pci_command );
245  new_command = ( pci_command | PCI_COMMAND_MASTER |
247  if ( pci_command != new_command ) {
248  DBGC ( pci, PCI_FMT " device not enabled by BIOS! Updating "
249  "PCI command %04x->%04x\n",
250  PCI_ARGS ( pci ), pci_command, new_command );
251  pci_write_config_word ( pci, PCI_COMMAND, new_command );
252  }
253 
254  pci_read_config_byte ( pci, PCI_LATENCY_TIMER, &pci_latency);
255  if ( pci_latency < 32 ) {
256  DBGC ( pci, PCI_FMT " latency timer is unreasonably low at "
257  "%d. Setting to 32.\n", PCI_ARGS ( pci ), pci_latency );
259  }
260 }
#define PCI_LATENCY_TIMER
PCI latency timer.
Definition: pci.h:50
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:25
#define PCI_COMMAND_MASTER
Bus master.
Definition: pci.h:28
#define PCI_COMMAND_IO
I/O space.
Definition: pci.h:26
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:311
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:314
#define PCI_COMMAND_MEM
Memory space.
Definition: pci.h:27
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 268 of file pci.c.

268  {
271  uint32_t tmp;
272 
273  /* Ignore all but the first function on non-multifunction devices */
274  if ( PCI_FUNC ( pci->busdevfn ) != 0 ) {
275  busdevfn = pci->busdevfn;
276  pci->busdevfn = PCI_FIRST_FUNC ( pci->busdevfn );
278  pci->busdevfn = busdevfn;
279  if ( ! ( hdrtype & PCI_HEADER_TYPE_MULTI ) )
280  return -ENODEV;
281  }
282 
283  /* Check for physical device presence */
285  if ( ( tmp == 0xffffffff ) || ( tmp == 0 ) )
286  return -ENODEV;
287 
288  /* Populate struct pci_device */
289  pci->vendor = ( tmp & 0xffff );
290  pci->device = ( tmp >> 16 );
292  pci->class = ( tmp >> 8 );
295  pci_read_bases ( pci );
296 
297  /* Initialise generic device component */
298  snprintf ( pci->dev.name, sizeof ( pci->dev.name ), "%04x:%02x:%02x.%x",
299  PCI_SEG ( pci->busdevfn ), PCI_BUS ( pci->busdevfn ),
300  PCI_SLOT ( pci->busdevfn ), PCI_FUNC ( pci->busdevfn ) );
301  pci->dev.desc.bus_type = BUS_TYPE_PCI;
302  pci->dev.desc.location = pci->busdevfn;
303  pci->dev.desc.vendor = pci->vendor;
304  pci->dev.desc.device = pci->device;
305  pci->dev.desc.class = pci->class;
306  pci->dev.desc.ioaddr = pci->ioaddr;
307  pci->dev.desc.irq = pci->irq;
308  INIT_LIST_HEAD ( &pci->dev.siblings );
309  INIT_LIST_HEAD ( &pci->dev.children );
310 
311  return 0;
312 }
#define PCI_FUNC(busdevfn)
Definition: pci.h:285
uint8_t irq
Interrupt number.
Definition: pci.h:233
#define PCI_BUS(busdevfn)
Definition: pci.h:283
uint32_t class
Device class.
Definition: pci.h:231
unsigned long ioaddr
I/O address.
Definition: pci.h:225
unsigned long ioaddr
I/O address.
Definition: device.h:37
#define PCI_INTERRUPT_LINE
PCI interrupt line.
Definition: pci.h:90
char name[40]
Name.
Definition: device.h:78
unsigned long class
Device class.
Definition: device.h:35
unsigned int vendor
Vendor ID.
Definition: device.h:31
struct device dev
Generic device.
Definition: pci.h:212
#define PCI_HEADER_TYPE
PCI header type.
Definition: pci.h:53
unsigned long tmp
Definition: linux_pci.h:64
uint16_t busdevfn
PCI bus:dev.fn address.
Definition: ena.h:28
uint16_t device
Device ID.
Definition: pci.h:229
#define BUS_TYPE_PCI
PCI bus type.
Definition: device.h:43
static void pci_read_bases(struct pci_device *pci)
Read membase and ioaddr for a PCI device.
Definition: pci.c:206
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:39
#define PCI_FIRST_FUNC(busdevfn)
Definition: pci.h:286
unsigned int location
Location.
Definition: device.h:29
uint8_t hdrtype
Header type.
Definition: pci.h:235
#define PCI_SLOT(busdevfn)
Definition: pci.h:284
struct list_head siblings
Devices on the same bus.
Definition: device.h:84
#define ENODEV
No such device.
Definition: errno.h:509
#define PCI_VENDOR_ID
PCI vendor ID.
Definition: pci.h:19
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
uint16_t vendor
Vendor ID.
Definition: pci.h:227
uint32_t busdevfn
Segment, bus, device, and function (bus:dev.fn) number.
Definition: pci.h:237
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
unsigned int bus_type
Bus type.
Definition: device.h:24
unsigned int device
Device ID.
Definition: device.h:33
struct list_head children
Devices attached to this device.
Definition: device.h:86
#define PCI_REVISION
PCI revision.
Definition: pci.h:44
struct device_description desc
Device description.
Definition: device.h:82
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
#define PCI_SEG(busdevfn)
Definition: pci.h:282
#define PCI_HEADER_TYPE_MULTI
Multi-function device.
Definition: pci.h:58
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 322 of file pci.c.

322  {
323  static struct pci_range range;
324  uint8_t hdrtype;
325  uint8_t sub;
326  uint32_t end;
327  unsigned int count;
328  int rc;
329 
330  /* Find next PCI device, if any */
331  do {
332  /* Find next PCI bus:dev.fn address range, if necessary */
333  if ( ( *busdevfn - range.start ) >= range.count ) {
334  pci_discover ( *busdevfn, &range );
335  if ( *busdevfn < range.start )
336  *busdevfn = range.start;
337  if ( ( *busdevfn - range.start ) >= range.count )
338  break;
339  }
340 
341  /* Check for PCI device existence */
342  memset ( pci, 0, sizeof ( *pci ) );
343  pci_init ( pci, *busdevfn );
344  if ( ( rc = pci_read_config ( pci ) ) != 0 )
345  continue;
346 
347  /* If device is a bridge, expand the PCI bus:dev.fn
348  * address range as needed.
349  */
350  pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
351  hdrtype &= PCI_HEADER_TYPE_MASK;
352  if ( hdrtype == PCI_HEADER_TYPE_BRIDGE ) {
353  pci_read_config_byte ( pci, PCI_SUBORDINATE, &sub );
354  end = PCI_BUSDEVFN ( PCI_SEG ( *busdevfn ),
355  ( sub + 1 ), 0, 0 );
356  count = ( end - range.start );
357  if ( count > range.count ) {
358  DBGC ( pci, PCI_FMT " found subordinate bus "
359  "%#02x\n", PCI_ARGS ( pci ), sub );
360  range.count = count;
361  }
362  }
363 
364  /* Return this device */
365  return 0;
366 
367  } while ( ++(*busdevfn) );
368 
369  return -ENODEV;
370 }
#define PCI_HEADER_TYPE_BRIDGE
PCI-to-PCI bridge header.
Definition: pci.h:55
uint32_t start
Starting bus:dev.fn address.
Definition: pci_io.h:24
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:57
#define DBGC(...)
Definition: compiler.h:505
#define PCI_HEADER_TYPE
PCI header type.
Definition: pci.h:53
uint16_t busdevfn
PCI bus:dev.fn address.
Definition: ena.h:28
A PCI bus:dev.fn address range.
Definition: pci_io.h:22
static unsigned int count
Number of entries.
Definition: dwmac.h:225
#define PCI_BUSDEVFN(segment, bus, slot, func)
Definition: pci_io.h:29
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:311
int pci_read_config(struct pci_device *pci)
Read PCI device configuration.
Definition: pci.c:268
#define ENODEV
No such device.
Definition: errno.h:509
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:26
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:314
uint32_t end
Ending offset.
Definition: netvsc.h:18
#define PCI_SUBORDINATE
Subordinate bus number.
Definition: pci.h:149
static void pci_init(struct pci_device *pci, unsigned int busdevfn)
Initialise PCI device.
Definition: pci.h:340
#define PCI_SEG(busdevfn)
Definition: pci.h:282
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 378 of file pci.c.

378  {
379  struct pci_driver *driver;
380  struct pci_device_id *id;
381  unsigned int i;
382 
383  for_each_table_entry ( driver, PCI_DRIVERS ) {
384  if ( ( driver->class.class ^ pci->class ) & driver->class.mask )
385  continue;
386  for ( i = 0 ; i < driver->id_count ; i++ ) {
387  id = &driver->ids[i];
388  if ( ( id->vendor != PCI_ANY_ID ) &&
389  ( id->vendor != pci->vendor ) )
390  continue;
391  if ( ( id->device != PCI_ANY_ID ) &&
392  ( id->device != pci->device ) )
393  continue;
394  pci_set_driver ( pci, driver, id );
395  return 0;
396  }
397  }
398  return -ENOENT;
399 }
struct pci_class_id class
PCI class ID.
Definition: pci.h:257
A PCI driver.
Definition: pci.h:251
uint32_t class
Device class.
Definition: pci.h:231
unsigned int id_count
Number of entries in PCI ID table.
Definition: pci.h:255
struct pci_device_id * ids
PCI ID table.
Definition: pci.h:253
static void pci_set_driver(struct pci_device *pci, struct pci_driver *driver, struct pci_device_id *id)
Set PCI driver.
Definition: pci.h:351
#define ENOENT
No such file or directory.
Definition: errno.h:514
uint32_t mask
Class mask.
Definition: pci.h:193
uint32_t class
Class.
Definition: pci.h:191
uint16_t device
Device ID.
Definition: pci.h:229
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:385
A PCI device ID list entry.
Definition: pci.h:174
uint16_t vendor
Vendor ID.
Definition: pci.h:227
#define PCI_ANY_ID
Match-anything ID.
Definition: pci.h:186
#define PCI_DRIVERS
PCI driver table.
Definition: pci.h:274

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 410 of file pci.c.

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

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 432 of file pci.c.

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

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 445 of file pci.c.

445  {
446  struct pci_device *pci = NULL;
447  uint32_t busdevfn = 0;
448  int rc;
449 
450  do {
451  /* Allocate struct pci_device */
452  if ( ! pci )
453  pci = malloc ( sizeof ( *pci ) );
454  if ( ! pci ) {
455  rc = -ENOMEM;
456  goto err;
457  }
458 
459  /* Find next PCI device, if any */
460  if ( ( rc = pci_find_next ( pci, &busdevfn ) ) != 0 )
461  break;
462 
463  /* Skip automatic probing if prohibited */
464  if ( ! pci_can_probe ( pci ) )
465  continue;
466 
467  /* Look for a driver */
468  if ( ( rc = pci_find_driver ( pci ) ) != 0 ) {
469  DBGC ( pci, PCI_FMT " (%04x:%04x class %06x) has no "
470  "driver\n", PCI_ARGS ( pci ), pci->vendor,
471  pci->device, pci->class );
472  continue;
473  }
474 
475  /* Add to device hierarchy */
476  pci->dev.parent = &rootdev->dev;
477  list_add ( &pci->dev.siblings, &rootdev->dev.children );
478 
479  /* Look for a driver */
480  if ( ( rc = pci_probe ( pci ) ) == 0 ) {
481  /* pcidev registered, we can drop our ref */
482  pci = NULL;
483  } else {
484  /* Not registered; re-use struct pci_device */
485  list_del ( &pci->dev.siblings );
486  }
487 
488  } while ( ++busdevfn );
489 
490  free ( pci );
491  return 0;
492 
493  err:
494  free ( pci );
495  pcibus_remove ( rootdev );
496  return rc;
497 }
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:378
uint32_t class
Device class.
Definition: pci.h:231
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:69
#define DBGC(...)
Definition: compiler.h:505
struct device dev
Device chain.
Definition: device.h:102
struct device * parent
Bus device.
Definition: device.h:88
struct device dev
Generic device.
Definition: pci.h:212
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
uint16_t busdevfn
PCI bus:dev.fn address.
Definition: ena.h:28
#define ENOMEM
Not enough space.
Definition: errno.h:534
int pci_find_next(struct pci_device *pci, uint32_t *busdevfn)
Find next device on PCI bus.
Definition: pci.c:322
uint16_t device
Device ID.
Definition: pci.h:229
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:311
struct list_head siblings
Devices on the same bus.
Definition: device.h:84
A PCI device.
Definition: pci.h:210
unsigned int uint32_t
Definition: stdint.h:12
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
uint16_t vendor
Vendor ID.
Definition: pci.h:227
static void pcibus_remove(struct root_device *rootdev)
Remove PCI root bus.
Definition: pci.c:504
struct list_head children
Devices attached to this device.
Definition: device.h:86
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:314
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
int pci_probe(struct pci_device *pci)
Probe a PCI device.
Definition: pci.c:410

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:445
static void pcibus_remove(struct root_device *rootdev)
Remove PCI root bus.
Definition: pci.c:504

PCI bus root device driver.

Definition at line 517 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:517

PCI bus root device.

Definition at line 523 of file pci.c.