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.
int pci_bar_is_io (struct pci_device *pci, unsigned int reg)
 Get PCI BAR type.
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 526 of file pci.c.

526 {
527 struct pci_device *pci;
528 struct pci_device *tmp;
529
530 list_for_each_entry_safe ( pci, tmp, &rootdev->dev.children,
531 dev.siblings ) {
532 pci_remove ( pci );
533 list_del ( &pci->dev.siblings );
534 free ( pci );
535 }
536}
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:454
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:214
struct device dev
Generic device.
Definition pci.h:216
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:530
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:315
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition pci.h:318
#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_is_io(), pci_bar_start(), and pci_read_bases().

◆ pci_bar_is_io()

int pci_bar_is_io ( struct pci_device * pci,
unsigned int reg )

Get PCI BAR type.

Parameters
pciPCI device
regPCI register number
is_ioBAR is an I/O BAR

Definition at line 90 of file pci.c.

90 {
91 unsigned long bar;
92
93 bar = pci_bar ( pci, reg );
94 return ( bar & PCI_BASE_ADDRESS_SPACE_IO );
95}
static unsigned long pci_bar(struct pci_device *pci, unsigned int reg)
Read PCI BAR.
Definition pci.c:61

References pci_bar(), PCI_BASE_ADDRESS_SPACE_IO, and reg.

Referenced by virtio_pci_map_cap().

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

111 {
112 unsigned long bar;
113
114 bar = pci_bar ( pci, reg );
115 if ( bar & PCI_BASE_ADDRESS_SPACE_IO ) {
116 return ( bar & ~PCI_BASE_ADDRESS_IO_MASK );
117 } else {
118 return ( bar & ~PCI_BASE_ADDRESS_MEM_MASK );
119 }
120}
#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_cap(), virtio_pci_map_cap(), 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 129 of file pci.c.

130 {
131 unsigned int type;
135
136 /* Save the original command register and disable decoding */
139 ( cmd & ~( PCI_COMMAND_MEM |
140 PCI_COMMAND_IO ) ) );
141
142 /* Check for a 64-bit BAR */
143 pci_read_config_dword ( pci, reg, &low );
146
147 /* Write low 32 bits */
148 low = start;
150
151 /* Write high 32 bits, if applicable */
153 if ( sizeof ( unsigned long ) > sizeof ( uint32_t ) ) {
154 high = ( ( ( uint64_t ) start ) >> 32 );
155 } else {
156 high = 0;
157 }
158 pci_write_config_dword ( pci, reg + 4, high );
159 }
160
161 /* Restore the original command register */
163}
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 178 of file pci.c.

178 {
179 unsigned long start;
180 unsigned long size;
182
183 /* Save the original command register and disable decoding */
186 ( cmd & ~( PCI_COMMAND_MEM |
187 PCI_COMMAND_IO ) ) );
188
189 /* Save the original start address */
190 start = pci_bar_start ( pci, reg );
191
192 /* Set all possible bits */
193 pci_bar_set ( pci, reg, -1UL );
194
195 /* Determine size by finding lowest set bit */
196 size = pci_bar_start ( pci, reg );
197 size &= ( -size );
198
199 /* Restore the original start address */
200 pci_bar_set ( pci, reg, start );
201
202 /* Restore the original command register */
204
205 return size;
206}
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:129
unsigned long pci_bar_start(struct pci_device *pci, unsigned int reg)
Find the start of a PCI BAR.
Definition pci.c:111

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

221 {
222 unsigned long bar;
223 int reg;
224
225 /* Clear any existing base addresses */
226 pci->ioaddr = 0;
227 pci->membase = 0;
228
229 /* Get first memory and I/O BAR addresses */
230 for ( reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4 ) {
231 bar = pci_bar ( pci, reg );
232 if ( bar & PCI_BASE_ADDRESS_SPACE_IO ) {
233 if ( ! pci->ioaddr )
234 pci->ioaddr =
236 } else {
237 if ( ! pci->membase )
238 pci->membase =
240 /* Skip next BAR if 64-bit */
242 reg += 4;
243 }
244 }
245}
#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:229
unsigned long membase
Memory base.
Definition pci.h:223

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

255 {
256 unsigned short new_command, pci_command;
257 unsigned char pci_latency;
258
259 pci_read_config_word ( pci, PCI_COMMAND, &pci_command );
260 new_command = ( pci_command | PCI_COMMAND_MASTER |
262 if ( pci_command != new_command ) {
263 DBGC ( pci, PCI_FMT " device not enabled by BIOS! Updating "
264 "PCI command %04x->%04x\n",
265 PCI_ARGS ( pci ), pci_command, new_command );
266 pci_write_config_word ( pci, PCI_COMMAND, new_command );
267 }
268
269 pci_read_config_byte ( pci, PCI_LATENCY_TIMER, &pci_latency);
270 if ( pci_latency < 32 ) {
271 DBGC ( pci, PCI_FMT " latency timer is unreasonably low at "
272 "%d. Setting to 32.\n", PCI_ARGS ( pci ), pci_latency );
274 }
275}
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(), virtio_pci_map(), 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 283 of file pci.c.

283 {
285 uint8_t hdrtype;
287
288 /* Ignore all but the first function on non-multifunction devices */
289 if ( PCI_FUNC ( pci->busdevfn ) != 0 ) {
290 busdevfn = pci->busdevfn;
291 pci->busdevfn = PCI_FIRST_FUNC ( pci->busdevfn );
292 pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
293 pci->busdevfn = busdevfn;
294 if ( ! ( hdrtype & PCI_HEADER_TYPE_MULTI ) )
295 return -ENODEV;
296 }
297
298 /* Check for physical device presence */
300 if ( ( tmp == 0xffffffff ) || ( tmp == 0 ) )
301 return -ENODEV;
302
303 /* Populate struct pci_device */
304 pci->vendor = ( tmp & 0xffff );
305 pci->device = ( tmp >> 16 );
307 pci->class = ( tmp >> 8 );
310 pci_read_bases ( pci );
311
312 /* Initialise generic device component */
313 snprintf ( pci->dev.name, sizeof ( pci->dev.name ), "%04x:%02x:%02x.%x",
314 PCI_SEG ( pci->busdevfn ), PCI_BUS ( pci->busdevfn ),
315 PCI_SLOT ( pci->busdevfn ), PCI_FUNC ( pci->busdevfn ) );
317 pci->dev.desc.location = pci->busdevfn;
318 pci->dev.desc.vendor = pci->vendor;
319 pci->dev.desc.device = pci->device;
320 pci->dev.desc.class = pci->class;
321 pci->dev.desc.ioaddr = pci->ioaddr;
322 pci->dev.desc.irq = pci->irq;
323 INIT_LIST_HEAD ( &pci->dev.siblings );
324 INIT_LIST_HEAD ( &pci->dev.children );
325
326 return 0;
327}
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:221
#define PCI_HEADER_TYPE
PCI header type.
Definition pci.h:54
#define PCI_SEG(busdevfn)
Definition pci.h:286
#define PCI_FUNC(busdevfn)
Definition pci.h:289
#define PCI_BUS(busdevfn)
Definition pci.h:287
#define PCI_FIRST_FUNC(busdevfn)
Definition pci.h:290
#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:288
#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:241
uint32_t class
Device class.
Definition pci.h:235
uint8_t hdrtype
Header type.
Definition pci.h:239
uint8_t irq
Interrupt number.
Definition pci.h:237
uint16_t vendor
Vendor ID.
Definition pci.h:231
uint16_t device
Device ID.
Definition pci.h:233
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 337 of file pci.c.

337 {
338 static struct pci_range range;
339 uint8_t hdrtype;
340 uint8_t sub;
342 unsigned int count;
343 int rc;
344
345 /* Find next PCI device, if any */
346 do {
347 /* Find next PCI bus:dev.fn address range, if necessary */
348 if ( ( *busdevfn - range.start ) >= range.count ) {
350 if ( *busdevfn < range.start )
351 *busdevfn = range.start;
352 if ( ( *busdevfn - range.start ) >= range.count )
353 break;
354 }
355
356 /* Check for PCI device existence */
357 memset ( pci, 0, sizeof ( *pci ) );
358 pci_init ( pci, *busdevfn );
359 if ( ( rc = pci_read_config ( pci ) ) != 0 )
360 continue;
361
362 /* If device is a bridge, expand the PCI bus:dev.fn
363 * address range as needed.
364 */
365 pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
366 hdrtype &= PCI_HEADER_TYPE_MASK;
367 if ( hdrtype == PCI_HEADER_TYPE_BRIDGE ) {
369 if ( sub <= PCI_BUS ( *busdevfn ) ) {
370 DBGC ( pci, PCI_FMT " ignoring invalid "
371 "subordinate bus %#02x\n",
372 PCI_ARGS ( pci ), sub );
373 } else {
375 ( sub + 1 ), 0, 0 );
376 count = ( end - range.start );
377 if ( count > range.count ) {
378 DBGC ( pci, PCI_FMT " found "
379 "subordinate bus %#02x\n",
380 PCI_ARGS ( pci ), sub );
381 range.count = count;
382 }
383 }
384 }
385
386 /* Return this device */
387 return 0;
388
389 } while ( ++(*busdevfn) );
390
391 return -ENODEV;
392}
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:283
#define PCI_SUBORDINATE
Subordinate bus number.
Definition pci.h:153
static void pci_init(struct pci_device *pci, unsigned int busdevfn)
Initialise PCI device.
Definition pci.h:345
#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 400 of file pci.c.

400 {
401 struct pci_driver *driver;
402 struct pci_device_id *id;
403 unsigned int i;
404
406 if ( ( driver->class.class ^ pci->class ) & driver->class.mask )
407 continue;
408 for ( i = 0 ; i < driver->id_count ; i++ ) {
409 id = &driver->ids[i];
410 if ( ( id->vendor != PCI_ANY_ID ) &&
411 ( id->vendor != pci->vendor ) )
412 continue;
413 if ( ( id->device != PCI_ANY_ID ) &&
414 ( id->device != pci->device ) )
415 continue;
416 pci_set_driver ( pci, driver, id );
417 return 0;
418 }
419 }
420 return -ENOENT;
421}
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:190
#define PCI_DRIVERS
PCI driver table.
Definition pci.h:278
static void pci_set_driver(struct pci_device *pci, struct pci_driver *driver, struct pci_device_id *id)
Set PCI driver.
Definition pci.h:356
uint32_t class
Class.
Definition pci.h:195
uint32_t mask
Class mask.
Definition pci.h:197
A PCI device ID list entry.
Definition pci.h:178
A PCI driver.
Definition pci.h:255
struct pci_class_id class
PCI class ID.
Definition pci.h:261
struct pci_device_id * ids
PCI ID table.
Definition pci.h:257
unsigned int id_count
Number of entries in PCI ID table.
Definition pci.h:259
#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 432 of file pci.c.

432 {
433 int rc;
434
435 DBGC ( pci, PCI_FMT " (%04x:%04x) has driver \"%s\"\n",
436 PCI_ARGS ( pci ), pci->vendor, pci->device, pci->id->name );
437 DBGC ( pci, PCI_FMT " has mem %lx io %lx irq %d\n",
438 PCI_ARGS ( pci ), pci->membase, pci->ioaddr, pci->irq );
439
440 if ( ( rc = pci->driver->probe ( pci ) ) != 0 ) {
441 DBGC ( pci, PCI_FMT " probe failed: %s\n",
442 PCI_ARGS ( pci ), strerror ( rc ) );
443 return rc;
444 }
445
446 return 0;
447}
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
const char * name
Name.
Definition pci.h:180
struct pci_driver * driver
Driver for this device.
Definition pci.h:243
struct pci_device_id * id
Driver device ID.
Definition pci.h:251
int(* probe)(struct pci_device *pci)
Probe device.
Definition pci.h:268

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

454 {
455 pci->driver->remove ( pci );
456 DBGC ( pci, PCI_FMT " removed\n", PCI_ARGS ( pci ) );
457}
void(* remove)(struct pci_device *pci)
Remove device.
Definition pci.h:274

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

467 {
468 struct pci_device *pci = NULL;
469 uint32_t busdevfn = 0;
470 int rc;
471
472 do {
473 /* Allocate struct pci_device */
474 if ( ! pci )
475 pci = malloc ( sizeof ( *pci ) );
476 if ( ! pci ) {
477 rc = -ENOMEM;
478 goto err;
479 }
480
481 /* Find next PCI device, if any */
482 if ( ( rc = pci_find_next ( pci, &busdevfn ) ) != 0 )
483 break;
484
485 /* Skip automatic probing if prohibited */
486 if ( ! pci_can_probe ( pci ) )
487 continue;
488
489 /* Look for a driver */
490 if ( ( rc = pci_find_driver ( pci ) ) != 0 ) {
491 DBGC ( pci, PCI_FMT " (%04x:%04x class %06x) has no "
492 "driver\n", PCI_ARGS ( pci ), pci->vendor,
493 pci->device, pci->class );
494 continue;
495 }
496
497 /* Add to device hierarchy */
498 pci->dev.parent = &rootdev->dev;
499 list_add ( &pci->dev.siblings, &rootdev->dev.children );
500
501 /* Look for a driver */
502 if ( ( rc = pci_probe ( pci ) ) == 0 ) {
503 /* pcidev registered, we can drop our ref */
504 pci = NULL;
505 } else {
506 /* Not registered; re-use struct pci_device */
507 list_del ( &pci->dev.siblings );
508 }
509
510 } while ( ++busdevfn );
511
512 free ( pci );
513 return 0;
514
515 err:
516 free ( pci );
517 pcibus_remove ( rootdev );
518 return rc;
519}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
#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:400
int pci_find_next(struct pci_device *pci, uint32_t *busdevfn)
Find next device on PCI bus.
Definition pci.c:337
int pci_probe(struct pci_device *pci)
Probe a PCI device.
Definition pci.c:432
static void pcibus_remove(struct root_device *rootdev)
Remove PCI root bus.
Definition pci.c:526
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:467

PCI bus root device driver.

Definition at line 539 of file pci.c.

539 {
540 .probe = pcibus_probe,
541 .remove = pcibus_remove,
542};

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

PCI bus root device.

Definition at line 545 of file pci.c.

545 {
546 .dev = { .name = "PCI" },
547 .driver = &pci_root_driver,
548};