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, unsigned int 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 400 of file pci.c.

400  {
401  struct pci_device *pci;
402  struct pci_device *tmp;
403 
404  list_for_each_entry_safe ( pci, tmp, &rootdev->dev.children,
405  dev.siblings ) {
406  pci_remove ( pci );
407  list_del ( &pci->dev.siblings );
408  free ( pci );
409  }
410 }
struct device dev
Device chain.
Definition: device.h:99
struct device dev
Generic device.
Definition: pci.h:193
#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:191
uint8_t * tmp
Definition: entropy.h:156
void pci_remove(struct pci_device *pci)
Remove a PCI device.
Definition: pci.c:331
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:293
#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:296

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  for ( reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4 ) {
125  bar = pci_bar ( pci, reg );
126  if ( bar & PCI_BASE_ADDRESS_SPACE_IO ) {
127  if ( ! pci->ioaddr )
128  pci->ioaddr =
129  ( bar & ~PCI_BASE_ADDRESS_IO_MASK );
130  } else {
131  if ( ! pci->membase )
132  pci->membase =
133  ( bar & ~PCI_BASE_ADDRESS_MEM_MASK );
134  /* Skip next BAR if 64-bit */
135  if ( bar & PCI_BASE_ADDRESS_MEM_TYPE_64 )
136  reg += 4;
137  }
138  }
139 }
unsigned long membase
Memory base.
Definition: pci.h:200
static unsigned int unsigned int reg
Definition: myson.h:162
unsigned long ioaddr
I/O address.
Definition: pci.h:206
#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 149 of file pci.c.

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

177  {
179  uint8_t hdrtype;
180  uint32_t tmp;
181 
182  /* Ignore all but the first function on non-multifunction devices */
183  if ( PCI_FUNC ( pci->busdevfn ) != 0 ) {
184  busdevfn = pci->busdevfn;
185  pci->busdevfn = PCI_FIRST_FUNC ( pci->busdevfn );
186  pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
187  pci->busdevfn = busdevfn;
188  if ( ! ( hdrtype & PCI_HEADER_TYPE_MULTI ) )
189  return -ENODEV;
190  }
191 
192  /* Check for physical device presence */
194  if ( ( tmp == 0xffffffff ) || ( tmp == 0 ) )
195  return -ENODEV;
196 
197  /* Populate struct pci_device */
198  pci->vendor = ( tmp & 0xffff );
199  pci->device = ( tmp >> 16 );
201  pci->class = ( tmp >> 8 );
203  pci_read_bases ( pci );
204 
205  /* Initialise generic device component */
206  snprintf ( pci->dev.name, sizeof ( pci->dev.name ), "%04x:%02x:%02x.%x",
207  PCI_SEG ( pci->busdevfn ), PCI_BUS ( pci->busdevfn ),
208  PCI_SLOT ( pci->busdevfn ), PCI_FUNC ( pci->busdevfn ) );
209  pci->dev.desc.bus_type = BUS_TYPE_PCI;
210  pci->dev.desc.location = pci->busdevfn;
211  pci->dev.desc.vendor = pci->vendor;
212  pci->dev.desc.device = pci->device;
213  pci->dev.desc.class = pci->class;
214  pci->dev.desc.ioaddr = pci->ioaddr;
215  pci->dev.desc.irq = pci->irq;
216  INIT_LIST_HEAD ( &pci->dev.siblings );
217  INIT_LIST_HEAD ( &pci->dev.children );
218 
219  return 0;
220 }
#define PCI_FUNC(busdevfn)
Definition: pci.h:264
uint8_t irq
Interrupt number.
Definition: pci.h:214
#define PCI_BUS(busdevfn)
Definition: pci.h:262
uint32_t class
Device class.
Definition: pci.h:212
unsigned long ioaddr
I/O address.
Definition: pci.h:206
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:193
#define PCI_HEADER_TYPE
PCI header type.
Definition: pci.h:53
uint16_t device
Device ID.
Definition: pci.h:210
#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:268
unsigned int location
Location.
Definition: device.h:29
#define PCI_SLOT(busdevfn)
Definition: pci.h:263
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:208
uint32_t busdevfn
Segment, bus, device, and function (bus:dev.fn) number.
Definition: pci.h:216
#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:261
#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, 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,
unsigned int  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, or negative error

Definition at line 229 of file pci.c.

229  {
230  static unsigned int end;
231  unsigned int sub_end;
232  uint8_t hdrtype;
233  uint8_t sub;
234  int rc;
235 
236  /* Determine number of PCI buses */
237  if ( ! end )
238  end = PCI_BUSDEVFN ( 0, pci_num_bus(), 0, 0 );
239 
240  /* Find next PCI device, if any */
241  for ( ; busdevfn < end ; busdevfn++ ) {
242 
243  /* Check for PCI device existence */
244  memset ( pci, 0, sizeof ( *pci ) );
245  pci_init ( pci, busdevfn );
246  if ( ( rc = pci_read_config ( pci ) ) != 0 )
247  continue;
248 
249  /* If device is a bridge, expand the number of PCI
250  * buses as needed.
251  */
252  pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
253  hdrtype &= PCI_HEADER_TYPE_MASK;
254  if ( hdrtype == PCI_HEADER_TYPE_BRIDGE ) {
255  pci_read_config_byte ( pci, PCI_SUBORDINATE, &sub );
256  sub_end = PCI_BUSDEVFN ( 0, ( sub + 1 ), 0, 0 );
257  if ( end < sub_end ) {
258  DBGC ( pci, PCI_FMT " found subordinate bus "
259  "%#02x\n", PCI_ARGS ( pci ), sub );
260  end = sub_end;
261  }
262  }
263 
264  /* Return this device */
265  return busdevfn;
266  }
267 
268  return -ENODEV;
269 }
#define PCI_HEADER_TYPE_BRIDGE
PCI-to-PCI bridge header.
Definition: pci.h:55
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define PCI_HEADER_TYPE_MASK
Header type mask.
Definition: pci.h:57
#define DBGC(...)
Definition: compiler.h:505
#define PCI_BUSDEVFN(segment, bus, slot, func)
Definition: pci.h:265
#define PCI_HEADER_TYPE
PCI header type.
Definition: pci.h:53
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:293
int pci_read_config(struct pci_device *pci)
Read PCI device configuration.
Definition: pci.c:177
#define ENODEV
No such device.
Definition: errno.h:509
unsigned char uint8_t
Definition: stdint.h:10
uint32_t busdevfn
Segment, bus, device, and function (bus:dev.fn) number.
Definition: pci.h:216
int pci_num_bus(void)
Determine number of PCI buses within system.
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:296
uint32_t end
Ending offset.
Definition: netvsc.h:18
#define PCI_SUBORDINATE
Subordinate bus number.
Definition: pci.h:139
static void pci_init(struct pci_device *pci, unsigned int busdevfn)
Initialise PCI device.
Definition: pci.h:319
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 DBGC, end, ENODEV, memset(), PCI_ARGS, PCI_BUSDEVFN, PCI_FMT, PCI_HEADER_TYPE, PCI_HEADER_TYPE_BRIDGE, PCI_HEADER_TYPE_MASK, pci_init(), pci_num_bus(), pci_read_config(), pci_read_config_byte(), PCI_SUBORDINATE, and rc.

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

277  {
278  struct pci_driver *driver;
279  struct pci_device_id *id;
280  unsigned int i;
281 
282  for_each_table_entry ( driver, PCI_DRIVERS ) {
283  if ( ( driver->class.class ^ pci->class ) & driver->class.mask )
284  continue;
285  for ( i = 0 ; i < driver->id_count ; i++ ) {
286  id = &driver->ids[i];
287  if ( ( id->vendor != PCI_ANY_ID ) &&
288  ( id->vendor != pci->vendor ) )
289  continue;
290  if ( ( id->device != PCI_ANY_ID ) &&
291  ( id->device != pci->device ) )
292  continue;
293  pci_set_driver ( pci, driver, id );
294  return 0;
295  }
296  }
297  return -ENOENT;
298 }
struct pci_class_id class
PCI class ID.
Definition: pci.h:236
A PCI driver.
Definition: pci.h:230
uint32_t class
Device class.
Definition: pci.h:212
unsigned int id_count
Number of entries in PCI ID table.
Definition: pci.h:234
struct pci_device_id * ids
PCI ID table.
Definition: pci.h:232
static void pci_set_driver(struct pci_device *pci, struct pci_driver *driver, struct pci_device_id *id)
Set PCI driver.
Definition: pci.h:330
#define ENOENT
No such file or directory.
Definition: errno.h:514
uint32_t mask
Class mask.
Definition: pci.h:174
uint32_t class
Class.
Definition: pci.h:172
uint16_t device
Device ID.
Definition: pci.h:210
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:358
A PCI device ID list entry.
Definition: pci.h:155
uint16_t vendor
Vendor ID.
Definition: pci.h:208
#define PCI_ANY_ID
Match-anything ID.
Definition: pci.h:167
#define PCI_DRIVERS
PCI driver table.
Definition: pci.h:253

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

309  {
310  int rc;
311 
312  DBGC ( pci, PCI_FMT " (%04x:%04x) has driver \"%s\"\n",
313  PCI_ARGS ( pci ), pci->vendor, pci->device, pci->id->name );
314  DBGC ( pci, PCI_FMT " has mem %lx io %lx irq %d\n",
315  PCI_ARGS ( pci ), pci->membase, pci->ioaddr, pci->irq );
316 
317  if ( ( rc = pci->driver->probe ( pci ) ) != 0 ) {
318  DBGC ( pci, PCI_FMT " probe failed: %s\n",
319  PCI_ARGS ( pci ), strerror ( rc ) );
320  return rc;
321  }
322 
323  return 0;
324 }
unsigned long membase
Memory base.
Definition: pci.h:200
uint8_t irq
Interrupt number.
Definition: pci.h:214
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct pci_driver * driver
Driver for this device.
Definition: pci.h:218
unsigned long ioaddr
I/O address.
Definition: pci.h:206
#define DBGC(...)
Definition: compiler.h:505
uint16_t device
Device ID.
Definition: pci.h:210
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:293
const char * name
Name.
Definition: pci.h:157
uint16_t vendor
Vendor ID.
Definition: pci.h:208
int(* probe)(struct pci_device *pci)
Probe device.
Definition: pci.h:243
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:296
struct pci_device_id * id
Driver device ID.
Definition: pci.h:226

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

331  {
332  pci->driver->remove ( pci );
333  DBGC ( pci, PCI_FMT " removed\n", PCI_ARGS ( pci ) );
334 }
struct pci_driver * driver
Driver for this device.
Definition: pci.h:218
void(* remove)(struct pci_device *pci)
Remove device.
Definition: pci.h:249
#define DBGC(...)
Definition: compiler.h:505
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:293
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:296

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

344  {
345  struct pci_device *pci = NULL;
346  int busdevfn = 0;
347  int rc;
348 
349  for ( busdevfn = 0 ; 1 ; busdevfn++ ) {
350 
351  /* Allocate struct pci_device */
352  if ( ! pci )
353  pci = malloc ( sizeof ( *pci ) );
354  if ( ! pci ) {
355  rc = -ENOMEM;
356  goto err;
357  }
358 
359  /* Find next PCI device, if any */
360  busdevfn = pci_find_next ( pci, busdevfn );
361  if ( busdevfn < 0 )
362  break;
363 
364  /* Look for a driver */
365  if ( ( rc = pci_find_driver ( pci ) ) != 0 ) {
366  DBGC ( pci, PCI_FMT " (%04x:%04x class %06x) has no "
367  "driver\n", PCI_ARGS ( pci ), pci->vendor,
368  pci->device, pci->class );
369  continue;
370  }
371 
372  /* Add to device hierarchy */
373  pci->dev.parent = &rootdev->dev;
374  list_add ( &pci->dev.siblings, &rootdev->dev.children );
375 
376  /* Look for a driver */
377  if ( ( rc = pci_probe ( pci ) ) == 0 ) {
378  /* pcidev registered, we can drop our ref */
379  pci = NULL;
380  } else {
381  /* Not registered; re-use struct pci_device */
382  list_del ( &pci->dev.siblings );
383  }
384  }
385 
386  free ( pci );
387  return 0;
388 
389  err:
390  free ( pci );
391  pcibus_remove ( rootdev );
392  return rc;
393 }
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:277
uint32_t class
Device class.
Definition: pci.h:212
#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:193
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define ENOMEM
Not enough space.
Definition: errno.h:534
uint16_t device
Device ID.
Definition: pci.h:210
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:293
struct list_head siblings
Devices on the same bus.
Definition: device.h:81
A PCI device.
Definition: pci.h:191
int pci_find_next(struct pci_device *pci, unsigned int busdevfn)
Find next device on PCI bus.
Definition: pci.c:229
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
uint16_t vendor
Vendor ID.
Definition: pci.h:208
uint32_t busdevfn
Segment, bus, device, and function (bus:dev.fn) number.
Definition: pci.h:216
static void pcibus_remove(struct root_device *rootdev)
Remove PCI root bus.
Definition: pci.c:400
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:296
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
int pci_probe(struct pci_device *pci)
Probe a PCI device.
Definition: pci.c:309

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

PCI bus root device driver.

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

PCI bus root device.

Definition at line 419 of file pci.c.