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

377  {
378  struct pci_device *pci;
379  struct pci_device *tmp;
380 
381  list_for_each_entry_safe ( pci, tmp, &rootdev->dev.children,
382  dev.siblings ) {
383  pci_remove ( pci );
384  list_del ( &pci->dev.siblings );
385  free ( pci );
386  }
387 }
struct device dev
Device chain.
Definition: device.h:99
struct device dev
Generic device.
Definition: pci.h:189
#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:187
uint8_t * tmp
Definition: entropy.h:156
void pci_remove(struct pci_device *pci)
Remove a PCI device.
Definition: pci.c:308
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 }
#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 low
Low 16 bits of address.
Definition: intel.h:21
#define PCI_BASE_ADDRESS_MEM_TYPE_64
64-bit memory
Definition: pci.h:69
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:287
static unsigned int unsigned int reg
Definition: intel.h:245
#define PCI_BASE_ADDRESS_MEM_TYPE_MASK
Memory type mask.
Definition: pci.h:70
unsigned int uint32_t
Definition: stdint.h:12
#define PCI_BASE_ADDRESS_SPACE_IO
I/O BAR.
Definition: pci.h:67
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:290
uint32_t high
High 32 bits of address.
Definition: intel.h:22

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 }
#define PCI_BASE_ADDRESS_IO_MASK
I/O BAR mask.
Definition: pci.h:68
#define PCI_BASE_ADDRESS_MEM_MASK
Memory BAR mask.
Definition: pci.h:71
static unsigned int unsigned int reg
Definition: intel.h:245
#define PCI_BASE_ADDRESS_SPACE_IO
I/O BAR.
Definition: pci.h:67
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(), 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:194
unsigned long ioaddr
I/O address.
Definition: pci.h:200
#define PCI_BASE_ADDRESS_0
Definition: pci.h:61
#define PCI_BASE_ADDRESS_5
Definition: pci.h:66
#define PCI_BASE_ADDRESS_IO_MASK
I/O BAR mask.
Definition: pci.h:68
#define PCI_BASE_ADDRESS_MEM_MASK
Memory BAR mask.
Definition: pci.h:71
#define PCI_BASE_ADDRESS_MEM_TYPE_64
64-bit memory
Definition: pci.h:69
static unsigned int unsigned int reg
Definition: intel.h:245
#define PCI_BASE_ADDRESS_SPACE_IO
I/O BAR.
Definition: pci.h:67
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:49
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:24
#define PCI_COMMAND_MASTER
Bus master.
Definition: pci.h:27
#define PCI_COMMAND_IO
I/O space.
Definition: pci.h:25
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:287
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:290
#define PCI_COMMAND_MEM
Memory space.
Definition: pci.h:26
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(), 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(), 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:258
uint8_t irq
Interrupt number.
Definition: pci.h:208
#define PCI_BUS(busdevfn)
Definition: pci.h:256
uint32_t class
Device class.
Definition: pci.h:206
unsigned long ioaddr
I/O address.
Definition: pci.h:200
unsigned long ioaddr
I/O address.
Definition: device.h:37
#define PCI_INTERRUPT_LINE
PCI interrupt line.
Definition: pci.h:89
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:189
#define PCI_HEADER_TYPE
PCI header type.
Definition: pci.h:52
uint16_t device
Device ID.
Definition: pci.h:204
#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:262
unsigned int location
Location.
Definition: device.h:29
#define PCI_SLOT(busdevfn)
Definition: pci.h:257
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:18
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
uint16_t vendor
Vendor ID.
Definition: pci.h:202
uint32_t busdevfn
Segment, bus, device, and function (bus:dev.fn) number.
Definition: pci.h:210
#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:43
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:255
#define PCI_HEADER_TYPE_MULTI
Multi-function device.
Definition: pci.h:57
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  int rc;
232 
233  /* Determine number of PCI buses */
234  if ( ! end )
235  end = PCI_BUSDEVFN ( 0, pci_num_bus(), 0, 0 );
236 
237  /* Find next PCI device, if any */
238  for ( ; busdevfn < end ; busdevfn++ ) {
239  memset ( pci, 0, sizeof ( *pci ) );
240  pci_init ( pci, busdevfn );
241  if ( ( rc = pci_read_config ( pci ) ) == 0 )
242  return busdevfn;
243  }
244 
245  return -ENODEV;
246 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define PCI_BUSDEVFN(segment, bus, slot, func)
Definition: pci.h:259
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
uint32_t busdevfn
Segment, bus, device, and function (bus:dev.fn) number.
Definition: pci.h:210
int pci_num_bus(void)
Determine number of PCI buses within system.
uint32_t end
Ending offset.
Definition: netvsc.h:18
static void pci_init(struct pci_device *pci, unsigned int busdevfn)
Initialise PCI device.
Definition: pci.h:313
void * memset(void *dest, int character, size_t len) __nonnull

References end, ENODEV, memset(), PCI_BUSDEVFN, pci_init(), pci_num_bus(), pci_read_config(), 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 254 of file pci.c.

254  {
255  struct pci_driver *driver;
256  struct pci_device_id *id;
257  unsigned int i;
258 
259  for_each_table_entry ( driver, PCI_DRIVERS ) {
260  if ( ( driver->class.class ^ pci->class ) & driver->class.mask )
261  continue;
262  for ( i = 0 ; i < driver->id_count ; i++ ) {
263  id = &driver->ids[i];
264  if ( ( id->vendor != PCI_ANY_ID ) &&
265  ( id->vendor != pci->vendor ) )
266  continue;
267  if ( ( id->device != PCI_ANY_ID ) &&
268  ( id->device != pci->device ) )
269  continue;
270  pci_set_driver ( pci, driver, id );
271  return 0;
272  }
273  }
274  return -ENOENT;
275 }
struct pci_class_id class
PCI class ID.
Definition: pci.h:230
A PCI driver.
Definition: pci.h:224
uint32_t class
Device class.
Definition: pci.h:206
unsigned int id_count
Number of entries in PCI ID table.
Definition: pci.h:228
struct pci_device_id * ids
PCI ID table.
Definition: pci.h:226
static void pci_set_driver(struct pci_device *pci, struct pci_driver *driver, struct pci_device_id *id)
Set PCI driver.
Definition: pci.h:324
#define ENOENT
No such file or directory.
Definition: errno.h:514
uint32_t mask
Class mask.
Definition: pci.h:170
uint32_t class
Class.
Definition: pci.h:168
uint16_t device
Device ID.
Definition: pci.h:204
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:151
uint16_t vendor
Vendor ID.
Definition: pci.h:202
#define PCI_ANY_ID
Match-anything ID.
Definition: pci.h:163
#define PCI_DRIVERS
PCI driver table.
Definition: pci.h:247

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

286  {
287  int rc;
288 
289  DBGC ( pci, PCI_FMT " (%04x:%04x) has driver \"%s\"\n",
290  PCI_ARGS ( pci ), pci->vendor, pci->device, pci->id->name );
291  DBGC ( pci, PCI_FMT " has mem %lx io %lx irq %d\n",
292  PCI_ARGS ( pci ), pci->membase, pci->ioaddr, pci->irq );
293 
294  if ( ( rc = pci->driver->probe ( pci ) ) != 0 ) {
295  DBGC ( pci, PCI_FMT " probe failed: %s\n",
296  PCI_ARGS ( pci ), strerror ( rc ) );
297  return rc;
298  }
299 
300  return 0;
301 }
unsigned long membase
Memory base.
Definition: pci.h:194
uint8_t irq
Interrupt number.
Definition: pci.h:208
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct pci_driver * driver
Driver for this device.
Definition: pci.h:212
unsigned long ioaddr
I/O address.
Definition: pci.h:200
#define DBGC(...)
Definition: compiler.h:505
uint16_t device
Device ID.
Definition: pci.h:204
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:287
const char * name
Name.
Definition: pci.h:153
uint16_t vendor
Vendor ID.
Definition: pci.h:202
int(* probe)(struct pci_device *pci)
Probe device.
Definition: pci.h:237
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:290
struct pci_device_id * id
Driver device ID.
Definition: pci.h:220

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

308  {
309  pci->driver->remove ( pci );
310  DBGC ( pci, PCI_FMT " removed\n", PCI_ARGS ( pci ) );
311 }
struct pci_driver * driver
Driver for this device.
Definition: pci.h:212
void(* remove)(struct pci_device *pci)
Remove device.
Definition: pci.h:243
#define DBGC(...)
Definition: compiler.h:505
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:287
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:290

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

321  {
322  struct pci_device *pci = NULL;
323  int busdevfn = 0;
324  int rc;
325 
326  for ( busdevfn = 0 ; 1 ; busdevfn++ ) {
327 
328  /* Allocate struct pci_device */
329  if ( ! pci )
330  pci = malloc ( sizeof ( *pci ) );
331  if ( ! pci ) {
332  rc = -ENOMEM;
333  goto err;
334  }
335 
336  /* Find next PCI device, if any */
337  busdevfn = pci_find_next ( pci, busdevfn );
338  if ( busdevfn < 0 )
339  break;
340 
341  /* Look for a driver */
342  if ( ( rc = pci_find_driver ( pci ) ) != 0 ) {
343  DBGC ( pci, PCI_FMT " (%04x:%04x class %06x) has no "
344  "driver\n", PCI_ARGS ( pci ), pci->vendor,
345  pci->device, pci->class );
346  continue;
347  }
348 
349  /* Add to device hierarchy */
350  pci->dev.parent = &rootdev->dev;
351  list_add ( &pci->dev.siblings, &rootdev->dev.children );
352 
353  /* Look for a driver */
354  if ( ( rc = pci_probe ( pci ) ) == 0 ) {
355  /* pcidev registered, we can drop our ref */
356  pci = NULL;
357  } else {
358  /* Not registered; re-use struct pci_device */
359  list_del ( &pci->dev.siblings );
360  }
361  }
362 
363  free ( pci );
364  return 0;
365 
366  err:
367  free ( pci );
368  pcibus_remove ( rootdev );
369  return rc;
370 }
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:254
uint32_t class
Device class.
Definition: pci.h:206
#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:189
#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:204
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:287
struct list_head siblings
Devices on the same bus.
Definition: device.h:81
A PCI device.
Definition: pci.h:187
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:202
uint32_t busdevfn
Segment, bus, device, and function (bus:dev.fn) number.
Definition: pci.h:210
static void pcibus_remove(struct root_device *rootdev)
Remove PCI root bus.
Definition: pci.c:377
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:290
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
int pci_probe(struct pci_device *pci)
Probe a PCI device.
Definition: pci.c:286

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

PCI bus root device driver.

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

PCI bus root device.

Definition at line 396 of file pci.c.