iPXE
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)
 FILE_SECBOOT (PERMITTED)
static void pcibus_remove (struct root_device *rootdev)
 Remove PCI root bus.
static unsigned long pci_bar (struct pci_device *pci, unsigned int reg)
 Read PCI BAR.
unsigned long pci_bar_start (struct pci_device *pci, unsigned int reg)
 Find the start of a PCI BAR.
void pci_bar_set (struct pci_device *pci, unsigned int reg, unsigned long start)
 Set the start of a PCI BAR.
unsigned long pci_bar_size (struct pci_device *pci, unsigned int reg)
 Get the size of a PCI BAR.
static void pci_read_bases (struct pci_device *pci)
 Read membase and ioaddr for a PCI device.
void adjust_pci_device (struct pci_device *pci)
 Enable PCI device.
int pci_read_config (struct pci_device *pci)
 Read PCI device configuration.
int pci_find_next (struct pci_device *pci, uint32_t *busdevfn)
 Find next device on PCI bus.
int pci_find_driver (struct pci_device *pci)
 Find driver for PCI device.
int pci_probe (struct pci_device *pci)
 Probe a PCI device.
void pci_remove (struct pci_device *pci)
 Remove a PCI device.
static int pcibus_probe (struct root_device *rootdev)
 Probe PCI root bus.
 REQUIRING_SYMBOL (pcibus_probe)
 REQUIRE_OBJECT (config_pci)

Variables

static struct root_driver pci_root_driver
 PCI bus root device driver.
struct root_device pci_root_device __root_device
 PCI bus root device.

Detailed Description

PCI bus.

Definition in file pci.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ pcibus_remove()

void pcibus_remove ( struct root_device * rootdev)
static

Remove PCI root bus.

Parameters
rootdevPCI bus root device

Definition at line 512 of file pci.c.

512 {
513 struct pci_device *pci;
514 struct pci_device *tmp;
515
516 list_for_each_entry_safe ( pci, tmp, &rootdev->dev.children,
517 dev.siblings ) {
518 pci_remove ( pci );
519 list_del ( &pci->dev.siblings );
520 free ( pci );
521 }
522}
unsigned long tmp
Definition linux_pci.h:65
#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:459
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
void pci_remove(struct pci_device *pci)
Remove a PCI device.
Definition pci.c:440
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
struct list_head children
Devices attached to this device.
Definition device.h:87
struct list_head siblings
Devices on the same bus.
Definition device.h:85
A PCI device.
Definition pci.h:211
struct device dev
Generic device.
Definition pci.h:213
struct device dev
Device chain.
Definition device.h:103

References device::children, pci_device::dev, root_device::dev, free, list_del, list_for_each_entry_safe, pci_remove(), device::siblings, and tmp.

Referenced by pcibus_probe().

◆ pci_bar()

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

61 {
64
65 pci_read_config_dword ( pci, reg, &low );
68 pci_read_config_dword ( pci, reg + 4, &high );
69 if ( high ) {
70 if ( sizeof ( unsigned long ) > sizeof ( uint32_t ) ) {
71 return ( ( ( uint64_t ) high << 32 ) | low );
72 } else {
73 DBGC ( pci, PCI_FMT " unhandled 64-bit BAR "
74 "%08x%08x\n",
75 PCI_ARGS ( pci ), high, low );
77 }
78 }
79 }
80 return low;
81}
unsigned int uint32_t
Definition stdint.h:12
unsigned long long uint64_t
Definition stdint.h:13
#define DBGC(...)
Definition compiler.h:505
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:1
uint32_t low
Low 16 bits of address.
Definition myson.h:0
static unsigned int unsigned int reg
Definition myson.h:162
#define PCI_BASE_ADDRESS_SPACE_IO
I/O BAR.
Definition pci.h:69
#define PCI_FMT
PCI device debug message format.
Definition pci.h:312
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition pci.h:315
#define PCI_BASE_ADDRESS_MEM_TYPE_MASK
Memory type mask.
Definition pci.h:72
#define PCI_BASE_ADDRESS_MEM_TYPE_64
64-bit memory
Definition pci.h:71

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

97 {
98 unsigned long bar;
99
100 bar = pci_bar ( pci, reg );
101 if ( bar & PCI_BASE_ADDRESS_SPACE_IO ) {
102 return ( bar & ~PCI_BASE_ADDRESS_IO_MASK );
103 } else {
104 return ( bar & ~PCI_BASE_ADDRESS_MEM_MASK );
105 }
106}
static unsigned long pci_bar(struct pci_device *pci, unsigned int reg)
Read PCI BAR.
Definition pci.c:61
#define PCI_BASE_ADDRESS_MEM_MASK
Memory BAR mask.
Definition pci.h:73
#define PCI_BASE_ADDRESS_IO_MASK
I/O BAR mask.
Definition pci.h:70

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(), ena_membases(), exanic_probe(), flexboot_nodnic_alloc_uar(), forcedeth_map_regs(), golan_alloc_uar(), golan_pci_init(), gve_probe(), hermon_bofm_probe(), hermon_probe(), hvm_probe(), igbvf_probe(), mlx_pci_init_priv(), pci_bar_size(), 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_bar_set()

void pci_bar_set ( struct pci_device * pci,
unsigned int reg,
unsigned long start )

Set the start of a PCI BAR.

Parameters
pciPCI device
regPCI register number
startBAR start address

Definition at line 115 of file pci.c.

116 {
117 unsigned int type;
121
122 /* Save the original command register and disable decoding */
125 ( cmd & ~( PCI_COMMAND_MEM |
126 PCI_COMMAND_IO ) ) );
127
128 /* Check for a 64-bit BAR */
129 pci_read_config_dword ( pci, reg, &low );
132
133 /* Write low 32 bits */
134 low = start;
136
137 /* Write high 32 bits, if applicable */
139 if ( sizeof ( unsigned long ) > sizeof ( uint32_t ) ) {
140 high = ( ( ( uint64_t ) start ) >> 32 );
141 } else {
142 high = 0;
143 }
144 pci_write_config_dword ( pci, reg + 4, high );
145 }
146
147 /* Restore the original command register */
149}
struct golan_eqe_cmd cmd
Definition CIB_PRM.h:1
unsigned short uint16_t
Definition stdint.h:11
uint32_t type
Operating system type.
Definition ena.h:1
uint32_t start
Starting offset.
Definition netvsc.h:1
int pci_read_config_word(struct pci_device *pci, unsigned int where, uint16_t *value)
Read 16-bit word from PCI configuration space.
int pci_write_config_word(struct pci_device *pci, unsigned int where, uint16_t value)
Write 16-bit word to PCI configuration space.
int pci_write_config_dword(struct pci_device *pci, unsigned int where, uint32_t value)
Write 32-bit dword to PCI configuration space.
#define PCI_COMMAND_MEM
Memory space.
Definition pci.h:28
#define PCI_COMMAND_IO
I/O space.
Definition pci.h:27
#define PCI_COMMAND
PCI command.
Definition pci.h:26

References cmd, high, low, PCI_BASE_ADDRESS_MEM_TYPE_64, PCI_BASE_ADDRESS_MEM_TYPE_MASK, PCI_BASE_ADDRESS_SPACE_IO, PCI_COMMAND, PCI_COMMAND_IO, PCI_COMMAND_MEM, pci_read_config_dword(), pci_read_config_word(), pci_write_config_dword(), pci_write_config_word(), reg, start, and type.

Referenced by ena_membases(), and pci_bar_size().

◆ pci_bar_size()

unsigned long pci_bar_size ( struct pci_device * pci,
unsigned int reg )

Get the size of a PCI BAR.

Parameters
pciPCI device
regPCI register number
Return values
sizeBAR size

Most drivers should not need to call this function. It is not necessary to map the whole PCI BAR, only the portion that will be used for register access. Since register offsets are almost always fixed by hardware design, the length of the mapped portion will almost always be a compile-time constant.

Definition at line 164 of file pci.c.

164 {
165 unsigned long start;
166 unsigned long size;
168
169 /* Save the original command register and disable decoding */
172 ( cmd & ~( PCI_COMMAND_MEM |
173 PCI_COMMAND_IO ) ) );
174
175 /* Save the original start address */
176 start = pci_bar_start ( pci, reg );
177
178 /* Set all possible bits */
179 pci_bar_set ( pci, reg, -1UL );
180
181 /* Determine size by finding lowest set bit */
182 size = pci_bar_start ( pci, reg );
183 size &= ( -size );
184
185 /* Restore the original start address */
186 pci_bar_set ( pci, reg, start );
187
188 /* Restore the original command register */
190
191 return size;
192}
uint16_t size
Buffer size.
Definition dwmac.h:3
void pci_bar_set(struct pci_device *pci, unsigned int reg, unsigned long start)
Set the start of a PCI BAR.
Definition pci.c:115
unsigned long pci_bar_start(struct pci_device *pci, unsigned int reg)
Find the start of a PCI BAR.
Definition pci.c:97

References cmd, pci_bar_set(), pci_bar_start(), PCI_COMMAND, PCI_COMMAND_IO, PCI_COMMAND_MEM, pci_read_config_word(), pci_write_config_word(), reg, size, and start.

Referenced by __vxge_hw_device_get_legacy_reg(), amd8111e_probe(), bnxt_pci_base(), efab_probe(), efx_probe(), ehci_probe(), ena_membases(), exanic_probe(), forcedeth_map_regs(), gve_probe(), hvm_probe(), igbvf_probe(), phantom_map_crb(), tg3_init_one(), virtio_pci_map_capability(), vxge_probe(), and xhci_probe().

◆ pci_read_bases()

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

207 {
208 unsigned long bar;
209 int reg;
210
211 /* Clear any existing base addresses */
212 pci->ioaddr = 0;
213 pci->membase = 0;
214
215 /* Get first memory and I/O BAR addresses */
216 for ( reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4 ) {
217 bar = pci_bar ( pci, reg );
218 if ( bar & PCI_BASE_ADDRESS_SPACE_IO ) {
219 if ( ! pci->ioaddr )
220 pci->ioaddr =
222 } else {
223 if ( ! pci->membase )
224 pci->membase =
226 /* Skip next BAR if 64-bit */
228 reg += 4;
229 }
230 }
231}
#define PCI_BASE_ADDRESS_0
Definition pci.h:63
#define PCI_BASE_ADDRESS_5
Definition pci.h:68
unsigned long ioaddr
I/O address.
Definition pci.h:226
unsigned long membase
Memory base.
Definition pci.h:220

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

241 {
242 unsigned short new_command, pci_command;
243 unsigned char pci_latency;
244
245 pci_read_config_word ( pci, PCI_COMMAND, &pci_command );
246 new_command = ( pci_command | PCI_COMMAND_MASTER |
248 if ( pci_command != new_command ) {
249 DBGC ( pci, PCI_FMT " device not enabled by BIOS! Updating "
250 "PCI command %04x->%04x\n",
251 PCI_ARGS ( pci ), pci_command, new_command );
252 pci_write_config_word ( pci, PCI_COMMAND, new_command );
253 }
254
255 pci_read_config_byte ( pci, PCI_LATENCY_TIMER, &pci_latency);
256 if ( pci_latency < 32 ) {
257 DBGC ( pci, PCI_FMT " latency timer is unreasonably low at "
258 "%d. Setting to 32.\n", PCI_ARGS ( pci ), pci_latency );
260 }
261}
int pci_write_config_byte(struct pci_device *pci, unsigned int where, uint8_t value)
Write byte to PCI configuration space.
int pci_read_config_byte(struct pci_device *pci, unsigned int where, uint8_t *value)
Read byte from PCI configuration space.
#define PCI_COMMAND_MASTER
Bus master.
Definition pci.h:29
#define PCI_LATENCY_TIMER
PCI latency timer.
Definition pci.h:51

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(), atl_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(), gve_probe(), 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 269 of file pci.c.

269 {
271 uint8_t hdrtype;
273
274 /* Ignore all but the first function on non-multifunction devices */
275 if ( PCI_FUNC ( pci->busdevfn ) != 0 ) {
276 busdevfn = pci->busdevfn;
277 pci->busdevfn = PCI_FIRST_FUNC ( pci->busdevfn );
278 pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
279 pci->busdevfn = busdevfn;
280 if ( ! ( hdrtype & PCI_HEADER_TYPE_MULTI ) )
281 return -ENODEV;
282 }
283
284 /* Check for physical device presence */
286 if ( ( tmp == 0xffffffff ) || ( tmp == 0 ) )
287 return -ENODEV;
288
289 /* Populate struct pci_device */
290 pci->vendor = ( tmp & 0xffff );
291 pci->device = ( tmp >> 16 );
293 pci->class = ( tmp >> 8 );
296 pci_read_bases ( pci );
297
298 /* Initialise generic device component */
299 snprintf ( pci->dev.name, sizeof ( pci->dev.name ), "%04x:%02x:%02x.%x",
300 PCI_SEG ( pci->busdevfn ), PCI_BUS ( pci->busdevfn ),
301 PCI_SLOT ( pci->busdevfn ), PCI_FUNC ( pci->busdevfn ) );
303 pci->dev.desc.location = pci->busdevfn;
304 pci->dev.desc.vendor = pci->vendor;
305 pci->dev.desc.device = pci->device;
306 pci->dev.desc.class = pci->class;
307 pci->dev.desc.ioaddr = pci->ioaddr;
308 pci->dev.desc.irq = pci->irq;
309 INIT_LIST_HEAD ( &pci->dev.siblings );
310 INIT_LIST_HEAD ( &pci->dev.children );
311
312 return 0;
313}
unsigned char uint8_t
Definition stdint.h:10
#define BUS_TYPE_PCI
PCI bus type.
Definition device.h:44
uint16_t busdevfn
PCI bus:dev.fn address.
Definition ena.h:17
#define ENODEV
No such device.
Definition errno.h:510
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
static void pci_read_bases(struct pci_device *pci)
Read membase and ioaddr for a PCI device.
Definition pci.c:207
#define PCI_HEADER_TYPE
PCI header type.
Definition pci.h:54
#define PCI_SEG(busdevfn)
Definition pci.h:283
#define PCI_FUNC(busdevfn)
Definition pci.h:286
#define PCI_BUS(busdevfn)
Definition pci.h:284
#define PCI_FIRST_FUNC(busdevfn)
Definition pci.h:287
#define PCI_INTERRUPT_LINE
PCI interrupt line.
Definition pci.h:91
#define PCI_HEADER_TYPE_MULTI
Multi-function device.
Definition pci.h:59
#define PCI_REVISION
PCI revision.
Definition pci.h:45
#define PCI_SLOT(busdevfn)
Definition pci.h:285
#define PCI_VENDOR_ID
PCI vendor ID.
Definition pci.h:20
unsigned int bus_type
Bus type.
Definition device.h:25
unsigned int device
Device ID.
Definition device.h:34
unsigned int vendor
Vendor ID.
Definition device.h:32
unsigned long class
Device class.
Definition device.h:36
unsigned int location
Location.
Definition device.h:30
unsigned int irq
IRQ.
Definition device.h:40
unsigned long ioaddr
I/O address.
Definition device.h:38
struct device_description desc
Device description.
Definition device.h:83
char name[40]
Name.
Definition device.h:79
uint32_t busdevfn
Segment, bus, device, and function (bus:dev.fn) number.
Definition pci.h:238
uint32_t class
Device class.
Definition pci.h:232
uint8_t hdrtype
Header type.
Definition pci.h:236
uint8_t irq
Interrupt number.
Definition pci.h:234
uint16_t vendor
Vendor ID.
Definition pci.h:228
uint16_t device
Device ID.
Definition pci.h:230
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383

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_info(), 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 323 of file pci.c.

323 {
324 static struct pci_range range;
325 uint8_t hdrtype;
326 uint8_t sub;
328 unsigned int count;
329 int rc;
330
331 /* Find next PCI device, if any */
332 do {
333 /* Find next PCI bus:dev.fn address range, if necessary */
334 if ( ( *busdevfn - range.start ) >= range.count ) {
336 if ( *busdevfn < range.start )
337 *busdevfn = range.start;
338 if ( ( *busdevfn - range.start ) >= range.count )
339 break;
340 }
341
342 /* Check for PCI device existence */
343 memset ( pci, 0, sizeof ( *pci ) );
344 pci_init ( pci, *busdevfn );
345 if ( ( rc = pci_read_config ( pci ) ) != 0 )
346 continue;
347
348 /* If device is a bridge, expand the PCI bus:dev.fn
349 * address range as needed.
350 */
351 pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
352 hdrtype &= PCI_HEADER_TYPE_MASK;
353 if ( hdrtype == PCI_HEADER_TYPE_BRIDGE ) {
355 if ( sub <= PCI_BUS ( *busdevfn ) ) {
356 DBGC ( pci, PCI_FMT " ignoring invalid "
357 "subordinate bus %#02x\n",
358 PCI_ARGS ( pci ), sub );
359 } else {
361 ( sub + 1 ), 0, 0 );
362 count = ( end - range.start );
363 if ( count > range.count ) {
364 DBGC ( pci, PCI_FMT " found "
365 "subordinate bus %#02x\n",
366 PCI_ARGS ( pci ), sub );
367 range.count = count;
368 }
369 }
370 }
371
372 /* Return this device */
373 return 0;
374
375 } while ( ++(*busdevfn) );
376
377 return -ENODEV;
378}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
static unsigned int count
Number of entries.
Definition dwmac.h:220
void pci_discover(uint32_t busdevfn, struct pci_range *range)
Find next PCI bus:dev.fn address range in system.
#define PCI_BUSDEVFN(segment, bus, slot, func)
Definition pci_io.h:30
void * memset(void *dest, int character, size_t len) __nonnull
uint32_t end
Ending offset.
Definition netvsc.h:7
int pci_read_config(struct pci_device *pci)
Read PCI device configuration.
Definition pci.c:269
#define PCI_SUBORDINATE
Subordinate bus number.
Definition pci.h:150
static void pci_init(struct pci_device *pci, unsigned int busdevfn)
Initialise PCI device.
Definition pci.h:341
#define PCI_HEADER_TYPE_MASK
Header type mask.
Definition pci.h:58
#define PCI_HEADER_TYPE_BRIDGE
PCI-to-PCI bridge header.
Definition pci.h:56
struct pci_range range
PCI bus:dev.fn address range.
Definition pcicloud.c:40
A PCI bus:dev.fn address range.
Definition pci_io.h:23

References busdevfn, count, DBGC, end, ENODEV, memset(), PCI_ARGS, PCI_BUS, 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, 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 386 of file pci.c.

386 {
387 struct pci_driver *driver;
388 struct pci_device_id *id;
389 unsigned int i;
390
392 if ( ( driver->class.class ^ pci->class ) & driver->class.mask )
393 continue;
394 for ( i = 0 ; i < driver->id_count ; i++ ) {
395 id = &driver->ids[i];
396 if ( ( id->vendor != PCI_ANY_ID ) &&
397 ( id->vendor != pci->vendor ) )
398 continue;
399 if ( ( id->device != PCI_ANY_ID ) &&
400 ( id->device != pci->device ) )
401 continue;
402 pci_set_driver ( pci, driver, id );
403 return 0;
404 }
405 }
406 return -ENOENT;
407}
uint8_t id
Request identifier.
Definition ena.h:1
#define ENOENT
No such file or directory.
Definition errno.h:515
#define PCI_ANY_ID
Match-anything ID.
Definition pci.h:187
#define PCI_DRIVERS
PCI driver table.
Definition pci.h:275
static void pci_set_driver(struct pci_device *pci, struct pci_driver *driver, struct pci_device_id *id)
Set PCI driver.
Definition pci.h:352
uint32_t class
Class.
Definition pci.h:192
uint32_t mask
Class mask.
Definition pci.h:194
A PCI device ID list entry.
Definition pci.h:175
A PCI driver.
Definition pci.h:252
struct pci_class_id class
PCI class ID.
Definition pci.h:258
struct pci_device_id * ids
PCI ID table.
Definition pci.h:254
unsigned int id_count
Number of entries in PCI ID table.
Definition pci.h:256
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386

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

418 {
419 int rc;
420
421 DBGC ( pci, PCI_FMT " (%04x:%04x) has driver \"%s\"\n",
422 PCI_ARGS ( pci ), pci->vendor, pci->device, pci->id->name );
423 DBGC ( pci, PCI_FMT " has mem %lx io %lx irq %d\n",
424 PCI_ARGS ( pci ), pci->membase, pci->ioaddr, pci->irq );
425
426 if ( ( rc = pci->driver->probe ( pci ) ) != 0 ) {
427 DBGC ( pci, PCI_FMT " probe failed: %s\n",
428 PCI_ARGS ( pci ), strerror ( rc ) );
429 return rc;
430 }
431
432 return 0;
433}
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
const char * name
Name.
Definition pci.h:177
struct pci_driver * driver
Driver for this device.
Definition pci.h:240
struct pci_device_id * id
Driver device ID.
Definition pci.h:248
int(* probe)(struct pci_device *pci)
Probe device.
Definition pci.h:265

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

440 {
441 pci->driver->remove ( pci );
442 DBGC ( pci, PCI_FMT " removed\n", PCI_ARGS ( pci ) );
443}
void(* remove)(struct pci_device *pci)
Remove device.
Definition pci.h:271

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()

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

453 {
454 struct pci_device *pci = NULL;
455 uint32_t busdevfn = 0;
456 int rc;
457
458 do {
459 /* Allocate struct pci_device */
460 if ( ! pci )
461 pci = malloc ( sizeof ( *pci ) );
462 if ( ! pci ) {
463 rc = -ENOMEM;
464 goto err;
465 }
466
467 /* Find next PCI device, if any */
468 if ( ( rc = pci_find_next ( pci, &busdevfn ) ) != 0 )
469 break;
470
471 /* Skip automatic probing if prohibited */
472 if ( ! pci_can_probe ( pci ) )
473 continue;
474
475 /* Look for a driver */
476 if ( ( rc = pci_find_driver ( pci ) ) != 0 ) {
477 DBGC ( pci, PCI_FMT " (%04x:%04x class %06x) has no "
478 "driver\n", PCI_ARGS ( pci ), pci->vendor,
479 pci->device, pci->class );
480 continue;
481 }
482
483 /* Add to device hierarchy */
484 pci->dev.parent = &rootdev->dev;
485 list_add ( &pci->dev.siblings, &rootdev->dev.children );
486
487 /* Look for a driver */
488 if ( ( rc = pci_probe ( pci ) ) == 0 ) {
489 /* pcidev registered, we can drop our ref */
490 pci = NULL;
491 } else {
492 /* Not registered; re-use struct pci_device */
493 list_del ( &pci->dev.siblings );
494 }
495
496 } while ( ++busdevfn );
497
498 free ( pci );
499 return 0;
500
501 err:
502 free ( pci );
503 pcibus_remove ( rootdev );
504 return rc;
505}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define ENOMEM
Not enough space.
Definition errno.h:535
int pci_can_probe(struct pci_device *pci)
Check if PCI bus probing is allowed.
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
int pci_find_driver(struct pci_device *pci)
Find driver for PCI device.
Definition pci.c:386
int pci_find_next(struct pci_device *pci, uint32_t *busdevfn)
Find next device on PCI bus.
Definition pci.c:323
int pci_probe(struct pci_device *pci)
Probe a PCI device.
Definition pci.c:418
static void pcibus_remove(struct root_device *rootdev)
Remove PCI root bus.
Definition pci.c:512
struct device * parent
Bus device.
Definition device.h:89

References busdevfn, device::children, pci_device::class, DBGC, pci_device::dev, root_device::dev, pci_device::device, ENOMEM, free, list_add, list_del, malloc(), NULL, device::parent, PCI_ARGS, pci_can_probe(), pci_find_driver(), pci_find_next(), PCI_FMT, pci_probe(), pcibus_remove(), rc, device::siblings, and pci_device::vendor.

Referenced by REQUIRING_SYMBOL().

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( pcibus_probe )

References pcibus_probe().

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( config_pci )

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:453

PCI bus root device driver.

Definition at line 525 of file pci.c.

525 {
526 .probe = pcibus_probe,
527 .remove = pcibus_remove,
528};

◆ __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:525

PCI bus root device.

Definition at line 531 of file pci.c.

531 {
532 .dev = { .name = "PCI" },
533 .driver = &pci_root_driver,
534};