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

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

413  {
414  struct pci_device *pci;
415  struct pci_device *tmp;
416 
417  list_for_each_entry_safe ( pci, tmp, &rootdev->dev.children,
418  dev.siblings ) {
419  pci_remove ( pci );
420  list_del ( &pci->dev.siblings );
421  free ( pci );
422  }
423 }
struct device dev
Device chain.
Definition: device.h:99
struct device dev
Generic device.
Definition: pci.h:208
#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:447
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct list_head siblings
Devices on the same bus.
Definition: device.h:81
A PCI device.
Definition: pci.h:206
uint8_t * tmp
Definition: entropy.h:156
void pci_remove(struct pci_device *pci)
Remove a PCI device.
Definition: pci.c:345
struct list_head children
Devices attached to this device.
Definition: device.h:83

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:305
#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:308

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(), exanic_probe(), flexboot_nodnic_alloc_uar(), forcedeth_map_regs(), golan_alloc_uar(), golan_pci_init(), hermon_bofm_probe(), hermon_probe(), hvm_probe(), igbvf_probe(), mlx_pci_init_priv(), 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_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 120 of file pci.c.

120  {
121  unsigned long bar;
122  int reg;
123 
124  /* Clear any existing base addresses */
125  pci->ioaddr = 0;
126  pci->membase = 0;
127 
128  /* Get first memory and I/O BAR addresses */
129  for ( reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4 ) {
130  bar = pci_bar ( pci, reg );
131  if ( bar & PCI_BASE_ADDRESS_SPACE_IO ) {
132  if ( ! pci->ioaddr )
133  pci->ioaddr =
134  ( bar & ~PCI_BASE_ADDRESS_IO_MASK );
135  } else {
136  if ( ! pci->membase )
137  pci->membase =
138  ( bar & ~PCI_BASE_ADDRESS_MEM_MASK );
139  /* Skip next BAR if 64-bit */
140  if ( bar & PCI_BASE_ADDRESS_MEM_TYPE_64 )
141  reg += 4;
142  }
143  }
144 }
unsigned long membase
Memory base.
Definition: pci.h:215
static unsigned int unsigned int reg
Definition: myson.h:162
unsigned long ioaddr
I/O address.
Definition: pci.h:221
#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 154 of file pci.c.

154  {
155  unsigned short new_command, pci_command;
156  unsigned char pci_latency;
157 
158  pci_read_config_word ( pci, PCI_COMMAND, &pci_command );
159  new_command = ( pci_command | PCI_COMMAND_MASTER |
161  if ( pci_command != new_command ) {
162  DBGC ( pci, PCI_FMT " device not enabled by BIOS! Updating "
163  "PCI command %04x->%04x\n",
164  PCI_ARGS ( pci ), pci_command, new_command );
165  pci_write_config_word ( pci, PCI_COMMAND, new_command );
166  }
167 
168  pci_read_config_byte ( pci, PCI_LATENCY_TIMER, &pci_latency);
169  if ( pci_latency < 32 ) {
170  DBGC ( pci, PCI_FMT " latency timer is unreasonably low at "
171  "%d. Setting to 32.\n", PCI_ARGS ( pci ), pci_latency );
173  }
174 }
#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:305
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:308
#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(), 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(), 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 182 of file pci.c.

182  {
184  uint8_t hdrtype;
185  uint32_t tmp;
186 
187  /* Ignore all but the first function on non-multifunction devices */
188  if ( PCI_FUNC ( pci->busdevfn ) != 0 ) {
189  busdevfn = pci->busdevfn;
190  pci->busdevfn = PCI_FIRST_FUNC ( pci->busdevfn );
191  pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
192  pci->busdevfn = busdevfn;
193  if ( ! ( hdrtype & PCI_HEADER_TYPE_MULTI ) )
194  return -ENODEV;
195  }
196 
197  /* Check for physical device presence */
199  if ( ( tmp == 0xffffffff ) || ( tmp == 0 ) )
200  return -ENODEV;
201 
202  /* Populate struct pci_device */
203  pci->vendor = ( tmp & 0xffff );
204  pci->device = ( tmp >> 16 );
206  pci->class = ( tmp >> 8 );
208  pci_read_bases ( pci );
209 
210  /* Initialise generic device component */
211  snprintf ( pci->dev.name, sizeof ( pci->dev.name ), "%04x:%02x:%02x.%x",
212  PCI_SEG ( pci->busdevfn ), PCI_BUS ( pci->busdevfn ),
213  PCI_SLOT ( pci->busdevfn ), PCI_FUNC ( pci->busdevfn ) );
214  pci->dev.desc.bus_type = BUS_TYPE_PCI;
215  pci->dev.desc.location = pci->busdevfn;
216  pci->dev.desc.vendor = pci->vendor;
217  pci->dev.desc.device = pci->device;
218  pci->dev.desc.class = pci->class;
219  pci->dev.desc.ioaddr = pci->ioaddr;
220  pci->dev.desc.irq = pci->irq;
221  INIT_LIST_HEAD ( &pci->dev.siblings );
222  INIT_LIST_HEAD ( &pci->dev.children );
223 
224  return 0;
225 }
#define PCI_FUNC(busdevfn)
Definition: pci.h:279
uint8_t irq
Interrupt number.
Definition: pci.h:229
#define PCI_BUS(busdevfn)
Definition: pci.h:277
uint32_t class
Device class.
Definition: pci.h:227
unsigned long ioaddr
I/O address.
Definition: pci.h:221
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:75
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:208
#define PCI_HEADER_TYPE
PCI header type.
Definition: pci.h:53
uint16_t busdevfn
PCI bus:dev.fn address.
Definition: ena.h:28
uint16_t device
Device ID.
Definition: pci.h:225
#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:120
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:280
unsigned int location
Location.
Definition: device.h:29
#define PCI_SLOT(busdevfn)
Definition: pci.h:278
struct list_head siblings
Devices on the same bus.
Definition: device.h:81
uint8_t * tmp
Definition: entropy.h:156
#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:223
uint32_t busdevfn
Segment, bus, device, and function (bus:dev.fn) number.
Definition: pci.h:231
#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:83
#define PCI_REVISION
PCI revision.
Definition: pci.h:44
struct device_description desc
Device description.
Definition: device.h:79
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:276
#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, 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_open(), 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 235 of file pci.c.

235  {
236  static struct pci_range range;
237  uint8_t hdrtype;
238  uint8_t sub;
239  uint32_t end;
240  unsigned int count;
241  int rc;
242 
243  /* Find next PCI device, if any */
244  do {
245  /* Find next PCI bus:dev.fn address range, if necessary */
246  if ( ( *busdevfn - range.start ) >= range.count ) {
247  pci_discover ( *busdevfn, &range );
248  if ( *busdevfn < range.start )
249  *busdevfn = range.start;
250  if ( ( *busdevfn - range.start ) >= range.count )
251  break;
252  }
253 
254  /* Check for PCI device existence */
255  memset ( pci, 0, sizeof ( *pci ) );
256  pci_init ( pci, *busdevfn );
257  if ( ( rc = pci_read_config ( pci ) ) != 0 )
258  continue;
259 
260  /* If device is a bridge, expand the PCI bus:dev.fn
261  * address range as needed.
262  */
263  pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
264  hdrtype &= PCI_HEADER_TYPE_MASK;
265  if ( hdrtype == PCI_HEADER_TYPE_BRIDGE ) {
266  pci_read_config_byte ( pci, PCI_SUBORDINATE, &sub );
267  end = PCI_BUSDEVFN ( PCI_SEG ( *busdevfn ),
268  ( sub + 1 ), 0, 0 );
269  count = ( end - range.start );
270  if ( count > range.count ) {
271  DBGC ( pci, PCI_FMT " found subordinate bus "
272  "%#02x\n", PCI_ARGS ( pci ), sub );
273  range.count = count;
274  }
275  }
276 
277  /* Return this device */
278  return 0;
279 
280  } while ( ++(*busdevfn) );
281 
282  return -ENODEV;
283 }
#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:23
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static __always_inline void struct pci_range * range
Definition: efi_pci_api.h:43
#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:21
#define PCI_BUSDEVFN(segment, bus, slot, func)
Definition: pci_io.h:28
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:305
int pci_read_config(struct pci_device *pci)
Read PCI device configuration.
Definition: pci.c:182
#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:25
void pci_discover(uint32_t busdevfn, struct pci_range *range)
Find next PCI bus:dev.fn address range in system.
uint16_t count
Number of entries.
Definition: ena.h:22
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:308
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:332
#define PCI_SEG(busdevfn)
Definition: pci.h:276
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, count, pci_range::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 291 of file pci.c.

291  {
292  struct pci_driver *driver;
293  struct pci_device_id *id;
294  unsigned int i;
295 
296  for_each_table_entry ( driver, PCI_DRIVERS ) {
297  if ( ( driver->class.class ^ pci->class ) & driver->class.mask )
298  continue;
299  for ( i = 0 ; i < driver->id_count ; i++ ) {
300  id = &driver->ids[i];
301  if ( ( id->vendor != PCI_ANY_ID ) &&
302  ( id->vendor != pci->vendor ) )
303  continue;
304  if ( ( id->device != PCI_ANY_ID ) &&
305  ( id->device != pci->device ) )
306  continue;
307  pci_set_driver ( pci, driver, id );
308  return 0;
309  }
310  }
311  return -ENOENT;
312 }
struct pci_class_id class
PCI class ID.
Definition: pci.h:251
A PCI driver.
Definition: pci.h:245
uint32_t class
Device class.
Definition: pci.h:227
unsigned int id_count
Number of entries in PCI ID table.
Definition: pci.h:249
struct pci_device_id * ids
PCI ID table.
Definition: pci.h:247
static void pci_set_driver(struct pci_device *pci, struct pci_driver *driver, struct pci_device_id *id)
Set PCI driver.
Definition: pci.h:343
#define ENOENT
No such file or directory.
Definition: errno.h:514
uint32_t mask
Class mask.
Definition: pci.h:189
uint32_t class
Class.
Definition: pci.h:187
uint16_t device
Device ID.
Definition: pci.h:225
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:170
uint16_t vendor
Vendor ID.
Definition: pci.h:223
#define PCI_ANY_ID
Match-anything ID.
Definition: pci.h:182
#define PCI_DRIVERS
PCI driver table.
Definition: pci.h:268

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

323  {
324  int rc;
325 
326  DBGC ( pci, PCI_FMT " (%04x:%04x) has driver \"%s\"\n",
327  PCI_ARGS ( pci ), pci->vendor, pci->device, pci->id->name );
328  DBGC ( pci, PCI_FMT " has mem %lx io %lx irq %d\n",
329  PCI_ARGS ( pci ), pci->membase, pci->ioaddr, pci->irq );
330 
331  if ( ( rc = pci->driver->probe ( pci ) ) != 0 ) {
332  DBGC ( pci, PCI_FMT " probe failed: %s\n",
333  PCI_ARGS ( pci ), strerror ( rc ) );
334  return rc;
335  }
336 
337  return 0;
338 }
unsigned long membase
Memory base.
Definition: pci.h:215
uint8_t irq
Interrupt number.
Definition: pci.h:229
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct pci_driver * driver
Driver for this device.
Definition: pci.h:233
unsigned long ioaddr
I/O address.
Definition: pci.h:221
#define DBGC(...)
Definition: compiler.h:505
uint16_t device
Device ID.
Definition: pci.h:225
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:305
const char * name
Name.
Definition: pci.h:172
uint16_t vendor
Vendor ID.
Definition: pci.h:223
int(* probe)(struct pci_device *pci)
Probe device.
Definition: pci.h:258
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:308
struct pci_device_id * id
Driver device ID.
Definition: pci.h:241

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

345  {
346  pci->driver->remove ( pci );
347  DBGC ( pci, PCI_FMT " removed\n", PCI_ARGS ( pci ) );
348 }
struct pci_driver * driver
Driver for this device.
Definition: pci.h:233
void(* remove)(struct pci_device *pci)
Remove device.
Definition: pci.h:264
#define DBGC(...)
Definition: compiler.h:505
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:305
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:308

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

358  {
359  struct pci_device *pci = NULL;
360  uint32_t busdevfn = 0;
361  int rc;
362 
363  do {
364  /* Allocate struct pci_device */
365  if ( ! pci )
366  pci = malloc ( sizeof ( *pci ) );
367  if ( ! pci ) {
368  rc = -ENOMEM;
369  goto err;
370  }
371 
372  /* Find next PCI device, if any */
373  if ( ( rc = pci_find_next ( pci, &busdevfn ) ) != 0 )
374  break;
375 
376  /* Look for a driver */
377  if ( ( rc = pci_find_driver ( pci ) ) != 0 ) {
378  DBGC ( pci, PCI_FMT " (%04x:%04x class %06x) has no "
379  "driver\n", PCI_ARGS ( pci ), pci->vendor,
380  pci->device, pci->class );
381  continue;
382  }
383 
384  /* Add to device hierarchy */
385  pci->dev.parent = &rootdev->dev;
386  list_add ( &pci->dev.siblings, &rootdev->dev.children );
387 
388  /* Look for a driver */
389  if ( ( rc = pci_probe ( pci ) ) == 0 ) {
390  /* pcidev registered, we can drop our ref */
391  pci = NULL;
392  } else {
393  /* Not registered; re-use struct pci_device */
394  list_del ( &pci->dev.siblings );
395  }
396 
397  } while ( ++busdevfn );
398 
399  free ( pci );
400  return 0;
401 
402  err:
403  free ( pci );
404  pcibus_remove ( rootdev );
405  return rc;
406 }
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:291
uint32_t class
Device class.
Definition: pci.h:227
#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:99
struct device * parent
Bus device.
Definition: device.h:85
struct device dev
Generic device.
Definition: pci.h:208
#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:235
uint16_t device
Device ID.
Definition: pci.h:225
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:305
struct list_head siblings
Devices on the same bus.
Definition: device.h:81
A PCI device.
Definition: pci.h:206
unsigned int uint32_t
Definition: stdint.h:12
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
uint16_t vendor
Vendor ID.
Definition: pci.h:223
static void pcibus_remove(struct root_device *rootdev)
Remove PCI root bus.
Definition: pci.c:413
struct list_head children
Devices attached to this device.
Definition: device.h:83
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:308
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
int pci_probe(struct pci_device *pci)
Probe a PCI device.
Definition: pci.c:323

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_find_driver(), pci_find_next(), PCI_FMT, pci_probe(), pcibus_remove(), rc, device::siblings, and pci_device::vendor.

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

PCI bus root device driver.

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

PCI bus root device.

Definition at line 432 of file pci.c.