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

405  {
406  struct pci_device *pci;
407  struct pci_device *tmp;
408 
409  list_for_each_entry_safe ( pci, tmp, &rootdev->dev.children,
410  dev.siblings ) {
411  pci_remove ( pci );
412  list_del ( &pci->dev.siblings );
413  free ( pci );
414  }
415 }
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:336
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  /* 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: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 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: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(), 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(), pci_reset(), 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: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 234 of file pci.c.

234  {
235  static unsigned int end;
236  unsigned int sub_end;
237  uint8_t hdrtype;
238  uint8_t sub;
239  int rc;
240 
241  /* Determine number of PCI buses */
242  if ( ! end )
243  end = PCI_BUSDEVFN ( 0, pci_num_bus(), 0, 0 );
244 
245  /* Find next PCI device, if any */
246  for ( ; busdevfn < end ; busdevfn++ ) {
247 
248  /* Check for PCI device existence */
249  memset ( pci, 0, sizeof ( *pci ) );
250  pci_init ( pci, busdevfn );
251  if ( ( rc = pci_read_config ( pci ) ) != 0 )
252  continue;
253 
254  /* If device is a bridge, expand the number of PCI
255  * buses as needed.
256  */
257  pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
258  hdrtype &= PCI_HEADER_TYPE_MASK;
259  if ( hdrtype == PCI_HEADER_TYPE_BRIDGE ) {
260  pci_read_config_byte ( pci, PCI_SUBORDINATE, &sub );
261  sub_end = PCI_BUSDEVFN ( 0, ( sub + 1 ), 0, 0 );
262  if ( end < sub_end ) {
263  DBGC ( pci, PCI_FMT " found subordinate bus "
264  "%#02x\n", PCI_ARGS ( pci ), sub );
265  end = sub_end;
266  }
267  }
268 
269  /* Return this device */
270  return busdevfn;
271  }
272 
273  return -ENODEV;
274 }
#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:182
#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:320
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 282 of file pci.c.

282  {
283  struct pci_driver *driver;
284  struct pci_device_id *id;
285  unsigned int i;
286 
287  for_each_table_entry ( driver, PCI_DRIVERS ) {
288  if ( ( driver->class.class ^ pci->class ) & driver->class.mask )
289  continue;
290  for ( i = 0 ; i < driver->id_count ; i++ ) {
291  id = &driver->ids[i];
292  if ( ( id->vendor != PCI_ANY_ID ) &&
293  ( id->vendor != pci->vendor ) )
294  continue;
295  if ( ( id->device != PCI_ANY_ID ) &&
296  ( id->device != pci->device ) )
297  continue;
298  pci_set_driver ( pci, driver, id );
299  return 0;
300  }
301  }
302  return -ENOENT;
303 }
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:331
#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:385
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 314 of file pci.c.

314  {
315  int rc;
316 
317  DBGC ( pci, PCI_FMT " (%04x:%04x) has driver \"%s\"\n",
318  PCI_ARGS ( pci ), pci->vendor, pci->device, pci->id->name );
319  DBGC ( pci, PCI_FMT " has mem %lx io %lx irq %d\n",
320  PCI_ARGS ( pci ), pci->membase, pci->ioaddr, pci->irq );
321 
322  if ( ( rc = pci->driver->probe ( pci ) ) != 0 ) {
323  DBGC ( pci, PCI_FMT " probe failed: %s\n",
324  PCI_ARGS ( pci ), strerror ( rc ) );
325  return rc;
326  }
327 
328  return 0;
329 }
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 336 of file pci.c.

336  {
337  pci->driver->remove ( pci );
338  DBGC ( pci, PCI_FMT " removed\n", PCI_ARGS ( pci ) );
339 }
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 349 of file pci.c.

349  {
350  struct pci_device *pci = NULL;
351  int busdevfn = 0;
352  int rc;
353 
354  for ( busdevfn = 0 ; 1 ; busdevfn++ ) {
355 
356  /* Allocate struct pci_device */
357  if ( ! pci )
358  pci = malloc ( sizeof ( *pci ) );
359  if ( ! pci ) {
360  rc = -ENOMEM;
361  goto err;
362  }
363 
364  /* Find next PCI device, if any */
365  busdevfn = pci_find_next ( pci, busdevfn );
366  if ( busdevfn < 0 )
367  break;
368 
369  /* Look for a driver */
370  if ( ( rc = pci_find_driver ( pci ) ) != 0 ) {
371  DBGC ( pci, PCI_FMT " (%04x:%04x class %06x) has no "
372  "driver\n", PCI_ARGS ( pci ), pci->vendor,
373  pci->device, pci->class );
374  continue;
375  }
376 
377  /* Add to device hierarchy */
378  pci->dev.parent = &rootdev->dev;
379  list_add ( &pci->dev.siblings, &rootdev->dev.children );
380 
381  /* Look for a driver */
382  if ( ( rc = pci_probe ( pci ) ) == 0 ) {
383  /* pcidev registered, we can drop our ref */
384  pci = NULL;
385  } else {
386  /* Not registered; re-use struct pci_device */
387  list_del ( &pci->dev.siblings );
388  }
389  }
390 
391  free ( pci );
392  return 0;
393 
394  err:
395  free ( pci );
396  pcibus_remove ( rootdev );
397  return rc;
398 }
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:282
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:234
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:405
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:314

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

PCI bus root device driver.

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

PCI bus root device.

Definition at line 424 of file pci.c.