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

414  {
415  struct pci_device *pci;
416  struct pci_device *tmp;
417 
418  list_for_each_entry_safe ( pci, tmp, &rootdev->dev.children,
419  dev.siblings ) {
420  pci_remove ( pci );
421  list_del ( &pci->dev.siblings );
422  free ( pci );
423  }
424 }
struct device dev
Device chain.
Definition: device.h:99
struct device dev
Generic device.
Definition: pci.h:208
unsigned long tmp
Definition: linux_pci.h:53
#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:81
A PCI device.
Definition: pci.h:206
void pci_remove(struct pci_device *pci)
Remove a PCI device.
Definition: pci.c:346
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:307
#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:310

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:307
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:310
#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  {
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 );
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 );
209  pci_read_bases ( pci );
210 
211  /* Initialise generic device component */
212  snprintf ( pci->dev.name, sizeof ( pci->dev.name ), "%04x:%02x:%02x.%x",
213  PCI_SEG ( pci->busdevfn ), PCI_BUS ( pci->busdevfn ),
214  PCI_SLOT ( pci->busdevfn ), PCI_FUNC ( pci->busdevfn ) );
215  pci->dev.desc.bus_type = BUS_TYPE_PCI;
216  pci->dev.desc.location = pci->busdevfn;
217  pci->dev.desc.vendor = pci->vendor;
218  pci->dev.desc.device = pci->device;
219  pci->dev.desc.class = pci->class;
220  pci->dev.desc.ioaddr = pci->ioaddr;
221  pci->dev.desc.irq = pci->irq;
222  INIT_LIST_HEAD ( &pci->dev.siblings );
223  INIT_LIST_HEAD ( &pci->dev.children );
224 
225  return 0;
226 }
#define PCI_FUNC(busdevfn)
Definition: pci.h:281
uint8_t irq
Interrupt number.
Definition: pci.h:229
#define PCI_BUS(busdevfn)
Definition: pci.h:279
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
unsigned long tmp
Definition: linux_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:282
unsigned int location
Location.
Definition: device.h:29
uint8_t hdrtype
Header type.
Definition: pci.h:231
#define PCI_SLOT(busdevfn)
Definition: pci.h:280
struct list_head siblings
Devices on the same bus.
Definition: device.h:81
#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:233
#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:278
#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_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 236 of file pci.c.

236  {
237  static struct pci_range range;
238  uint8_t hdrtype;
239  uint8_t sub;
240  uint32_t end;
241  unsigned int count;
242  int rc;
243 
244  /* Find next PCI device, if any */
245  do {
246  /* Find next PCI bus:dev.fn address range, if necessary */
247  if ( ( *busdevfn - range.start ) >= range.count ) {
248  pci_discover ( *busdevfn, &range );
249  if ( *busdevfn < range.start )
250  *busdevfn = range.start;
251  if ( ( *busdevfn - range.start ) >= range.count )
252  break;
253  }
254 
255  /* Check for PCI device existence */
256  memset ( pci, 0, sizeof ( *pci ) );
257  pci_init ( pci, *busdevfn );
258  if ( ( rc = pci_read_config ( pci ) ) != 0 )
259  continue;
260 
261  /* If device is a bridge, expand the PCI bus:dev.fn
262  * address range as needed.
263  */
264  pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
265  hdrtype &= PCI_HEADER_TYPE_MASK;
266  if ( hdrtype == PCI_HEADER_TYPE_BRIDGE ) {
267  pci_read_config_byte ( pci, PCI_SUBORDINATE, &sub );
268  end = PCI_BUSDEVFN ( PCI_SEG ( *busdevfn ),
269  ( sub + 1 ), 0, 0 );
270  count = ( end - range.start );
271  if ( count > range.count ) {
272  DBGC ( pci, PCI_FMT " found subordinate bus "
273  "%#02x\n", PCI_ARGS ( pci ), sub );
274  range.count = count;
275  }
276  }
277 
278  /* Return this device */
279  return 0;
280 
281  } while ( ++(*busdevfn) );
282 
283  return -ENODEV;
284 }
#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:307
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:310
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:334
#define PCI_SEG(busdevfn)
Definition: pci.h:278
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(), pcicloud_init(), 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 292 of file pci.c.

292  {
293  struct pci_driver *driver;
294  struct pci_device_id *id;
295  unsigned int i;
296 
297  for_each_table_entry ( driver, PCI_DRIVERS ) {
298  if ( ( driver->class.class ^ pci->class ) & driver->class.mask )
299  continue;
300  for ( i = 0 ; i < driver->id_count ; i++ ) {
301  id = &driver->ids[i];
302  if ( ( id->vendor != PCI_ANY_ID ) &&
303  ( id->vendor != pci->vendor ) )
304  continue;
305  if ( ( id->device != PCI_ANY_ID ) &&
306  ( id->device != pci->device ) )
307  continue;
308  pci_set_driver ( pci, driver, id );
309  return 0;
310  }
311  }
312  return -ENOENT;
313 }
struct pci_class_id class
PCI class ID.
Definition: pci.h:253
A PCI driver.
Definition: pci.h:247
uint32_t class
Device class.
Definition: pci.h:227
unsigned int id_count
Number of entries in PCI ID table.
Definition: pci.h:251
struct pci_device_id * ids
PCI ID table.
Definition: pci.h:249
static void pci_set_driver(struct pci_device *pci, struct pci_driver *driver, struct pci_device_id *id)
Set PCI driver.
Definition: pci.h:345
#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:270

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

324  {
325  int rc;
326 
327  DBGC ( pci, PCI_FMT " (%04x:%04x) has driver \"%s\"\n",
328  PCI_ARGS ( pci ), pci->vendor, pci->device, pci->id->name );
329  DBGC ( pci, PCI_FMT " has mem %lx io %lx irq %d\n",
330  PCI_ARGS ( pci ), pci->membase, pci->ioaddr, pci->irq );
331 
332  if ( ( rc = pci->driver->probe ( pci ) ) != 0 ) {
333  DBGC ( pci, PCI_FMT " probe failed: %s\n",
334  PCI_ARGS ( pci ), strerror ( rc ) );
335  return rc;
336  }
337 
338  return 0;
339 }
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:235
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:307
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:260
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:310
struct pci_device_id * id
Driver device ID.
Definition: pci.h:243

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

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

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

359  {
360  struct pci_device *pci = NULL;
361  uint32_t busdevfn = 0;
362  int rc;
363 
364  do {
365  /* Allocate struct pci_device */
366  if ( ! pci )
367  pci = malloc ( sizeof ( *pci ) );
368  if ( ! pci ) {
369  rc = -ENOMEM;
370  goto err;
371  }
372 
373  /* Find next PCI device, if any */
374  if ( ( rc = pci_find_next ( pci, &busdevfn ) ) != 0 )
375  break;
376 
377  /* Look for a driver */
378  if ( ( rc = pci_find_driver ( pci ) ) != 0 ) {
379  DBGC ( pci, PCI_FMT " (%04x:%04x class %06x) has no "
380  "driver\n", PCI_ARGS ( pci ), pci->vendor,
381  pci->device, pci->class );
382  continue;
383  }
384 
385  /* Add to device hierarchy */
386  pci->dev.parent = &rootdev->dev;
387  list_add ( &pci->dev.siblings, &rootdev->dev.children );
388 
389  /* Look for a driver */
390  if ( ( rc = pci_probe ( pci ) ) == 0 ) {
391  /* pcidev registered, we can drop our ref */
392  pci = NULL;
393  } else {
394  /* Not registered; re-use struct pci_device */
395  list_del ( &pci->dev.siblings );
396  }
397 
398  } while ( ++busdevfn );
399 
400  free ( pci );
401  return 0;
402 
403  err:
404  free ( pci );
405  pcibus_remove ( rootdev );
406  return rc;
407 }
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:292
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:236
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:307
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:414
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:310
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
int pci_probe(struct pci_device *pci)
Probe a PCI device.
Definition: pci.c:324

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

PCI bus root device driver.

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

PCI bus root device.

Definition at line 433 of file pci.c.