#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <gpxe/tables.h>
#include <gpxe/device.h>
#include <gpxe/pci.h>
Go to the source code of this file.
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| 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. | |
| 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. | |
| static int | pci_probe (struct pci_device *pci) |
| Probe a PCI device. | |
| static void | pci_remove (struct pci_device *pci) |
| Remove a PCI device. | |
| static int | pcibus_probe (struct root_device *rootdev) |
| Probe PCI root bus. | |
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. | |
Definition in file pci.c.
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| static void pcibus_remove | ( | struct root_device * | rootdev | ) | [static] |
Remove PCI root bus.
| rootdev | PCI bus root device |
Definition at line 319 of file pci.c.
References device::children, pci_device::dev, root_device::dev, free(), list_del, list_for_each_entry_safe, pci_remove(), and device::siblings.
Referenced by pcibus_probe().
00319 { 00320 struct pci_device *pci; 00321 struct pci_device *tmp; 00322 00323 list_for_each_entry_safe ( pci, tmp, &rootdev->dev.children, 00324 dev.siblings ) { 00325 pci_remove ( pci ); 00326 list_del ( &pci->dev.siblings ); 00327 free ( pci ); 00328 } 00329 }
| static unsigned long pci_bar | ( | struct pci_device * | pci, | |
| unsigned int | reg | |||
| ) | [static] |
Read PCI BAR.
| pci | PCI device | |
| reg | PCI register number |
| bar | Base address register |
Definition at line 55 of file pci.c.
References DBG, PCI_BASE_ADDRESS_MEM_TYPE_64, PCI_BASE_ADDRESS_MEM_TYPE_MASK, PCI_BASE_ADDRESS_SPACE, PCI_BASE_ADDRESS_SPACE_MEMORY, and pci_read_config_dword().
Referenced by pci_bar_start(), and pci_read_bases().
00055 { 00056 uint32_t low; 00057 uint32_t high; 00058 00059 pci_read_config_dword ( pci, reg, &low ); 00060 if ( ( low & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK) ) 00061 == (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64) ){ 00062 pci_read_config_dword ( pci, reg + 4, &high ); 00063 if ( high ) { 00064 if ( sizeof ( unsigned long ) > sizeof ( uint32_t ) ) { 00065 return ( ( ( uint64_t ) high << 32 ) | low ); 00066 } else { 00067 DBG ( "Unhandled 64-bit BAR %08x%08x\n", 00068 high, low ); 00069 return PCI_BASE_ADDRESS_MEM_TYPE_64; 00070 } 00071 } 00072 } 00073 return low; 00074 }
| unsigned long pci_bar_start | ( | struct pci_device * | pci, | |
| unsigned int | reg | |||
| ) |
Find the start of a PCI BAR.
| pci | PCI device | |
| reg | PCI register number |
| start | BAR start address |
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 90 of file pci.c.
References pci_bar(), PCI_BASE_ADDRESS_IO_MASK, PCI_BASE_ADDRESS_MEM_MASK, PCI_BASE_ADDRESS_SPACE, and PCI_BASE_ADDRESS_SPACE_MEMORY.
Referenced by amd8111e_probe(), arbel_probe(), bnx2_init_board(), dmfe_probe(), e1000_probe(), e1000e_probe(), efab_probe(), forcedeth_probe(), hermon_probe(), igb_probe(), mtnic_init_pci(), ns83820_probe(), phantom_map_crb(), skge_probe(), sky2_probe(), tg3_probe(), undipci_find_rom(), velocity_get_pci_info(), and vxge_probe().
00090 { 00091 unsigned long bar; 00092 00093 bar = pci_bar ( pci, reg ); 00094 if ( (bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY ){ 00095 return ( bar & PCI_BASE_ADDRESS_MEM_MASK ); 00096 } else { 00097 return ( bar & PCI_BASE_ADDRESS_IO_MASK ); 00098 } 00099 }
| static void pci_read_bases | ( | struct pci_device * | pci | ) | [static] |
Read membase and ioaddr for a PCI device.
| pci | PCI device |
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 114 of file pci.c.
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, and PCI_BASE_ADDRESS_SPACE_IO.
Referenced by pcibus_probe().
00114 { 00115 unsigned long bar; 00116 int reg; 00117 00118 for ( reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4 ) { 00119 bar = pci_bar ( pci, reg ); 00120 if ( bar & PCI_BASE_ADDRESS_SPACE_IO ) { 00121 if ( ! pci->ioaddr ) 00122 pci->ioaddr = 00123 ( bar & PCI_BASE_ADDRESS_IO_MASK ); 00124 } else { 00125 if ( ! pci->membase ) 00126 pci->membase = 00127 ( bar & PCI_BASE_ADDRESS_MEM_MASK ); 00128 /* Skip next BAR if 64-bit */ 00129 if ( bar & PCI_BASE_ADDRESS_MEM_TYPE_64 ) 00130 reg += 4; 00131 } 00132 } 00133 }
| void adjust_pci_device | ( | struct pci_device * | pci | ) |
Enable PCI device.
| pci | PCI device |
Definition at line 143 of file pci.c.
References pci_device::bus, DBG, pci_device::devfn, PCI_COMMAND, PCI_COMMAND_IO, PCI_COMMAND_MASTER, PCI_COMMAND_MEM, PCI_FUNC, PCI_LATENCY_TIMER, pci_read_config_byte(), pci_read_config_word(), PCI_SLOT, pci_write_config_byte(), and pci_write_config_word().
Referenced by a3c90x_probe(), amd8111e_probe(), arbel_probe(), ath5k_probe(), atl1e_probe(), b44_probe(), bnx2_init_board(), dmfe_probe(), e1000_probe(), e1000e_probe(), efab_probe(), forcedeth_probe(), hermon_probe(), ifec_pci_probe(), igb_probe(), linda_probe(), mtd_probe(), mtnic_probe(), myri10ge_pci_probe(), natsemi_probe(), ns83820_probe(), pcnet32_probe(), phantom_probe(), pnic_probe(), rhine_probe(), rtl8169_probe(), rtl818x_probe(), rtl_probe(), sis190_init_board(), sis900_probe(), skge_probe(), sky2_probe(), sundance_probe(), tg3_probe(), tlan_probe(), tulip_probe(), velocity_get_pci_info(), virtnet_probe(), vxge_probe(), and w89c840_probe().
00143 { 00144 unsigned short new_command, pci_command; 00145 unsigned char pci_latency; 00146 00147 pci_read_config_word ( pci, PCI_COMMAND, &pci_command ); 00148 new_command = ( pci_command | PCI_COMMAND_MASTER | 00149 PCI_COMMAND_MEM | PCI_COMMAND_IO ); 00150 if ( pci_command != new_command ) { 00151 DBG ( "PCI BIOS has not enabled device %02x:%02x.%x! " 00152 "Updating PCI command %04x->%04x\n", pci->bus, 00153 PCI_SLOT ( pci->devfn ), PCI_FUNC ( pci->devfn ), 00154 pci_command, new_command ); 00155 pci_write_config_word ( pci, PCI_COMMAND, new_command ); 00156 } 00157 00158 pci_read_config_byte ( pci, PCI_LATENCY_TIMER, &pci_latency); 00159 if ( pci_latency < 32 ) { 00160 DBG ( "PCI device %02x:%02x.%x latency timer is unreasonably " 00161 "low at %d. Setting to 32.\n", pci->bus, 00162 PCI_SLOT ( pci->devfn ), PCI_FUNC ( pci->devfn ), 00163 pci_latency ); 00164 pci_write_config_byte ( pci, PCI_LATENCY_TIMER, 32); 00165 } 00166 }
| static int pci_probe | ( | struct pci_device * | pci | ) | [static] |
Probe a PCI device.
| pci | PCI device |
| rc | Return status code |
Definition at line 177 of file pci.c.
References pci_device::bus, DBG, pci_device::devfn, pci_device_id::device, pci_device::device, pci_device::driver, pci_device::driver_name, ENOTTY, for_each_table_entry, id, pci_driver::id_count, pci_driver::ids, pci_device::ioaddr, pci_device::irq, pci_device::membase, PCI_ANY_ID, PCI_DRIVERS, PCI_FUNC, PCI_SLOT, pci_driver::probe, pci_device_id::vendor, and pci_device::vendor.
Referenced by pcibus_probe().
00177 { 00178 struct pci_driver *driver; 00179 struct pci_device_id *id; 00180 unsigned int i; 00181 int rc; 00182 00183 DBG ( "Adding PCI device %02x:%02x.%x (%04x:%04x mem %lx io %lx " 00184 "irq %d)\n", pci->bus, PCI_SLOT ( pci->devfn ), 00185 PCI_FUNC ( pci->devfn ), pci->vendor, pci->device, 00186 pci->membase, pci->ioaddr, pci->irq ); 00187 00188 for_each_table_entry ( driver, PCI_DRIVERS ) { 00189 for ( i = 0 ; i < driver->id_count ; i++ ) { 00190 id = &driver->ids[i]; 00191 if ( ( id->vendor != PCI_ANY_ID ) && 00192 ( id->vendor != pci->vendor ) ) 00193 continue; 00194 if ( ( id->device != PCI_ANY_ID ) && 00195 ( id->device != pci->device ) ) 00196 continue; 00197 pci->driver = driver; 00198 pci->driver_name = id->name; 00199 DBG ( "...using driver %s\n", pci->driver_name ); 00200 if ( ( rc = driver->probe ( pci, id ) ) != 0 ) { 00201 DBG ( "......probe failed\n" ); 00202 continue; 00203 } 00204 return 0; 00205 } 00206 } 00207 00208 DBG ( "...no driver found\n" ); 00209 return -ENOTTY; 00210 }
| static void pci_remove | ( | struct pci_device * | pci | ) | [static] |
Remove a PCI device.
| pci | PCI device |
Definition at line 217 of file pci.c.
References pci_device::bus, DBG, pci_device::devfn, pci_device::driver, PCI_FUNC, PCI_SLOT, and pci_driver::remove.
Referenced by pcibus_remove().
00217 { 00218 pci->driver->remove ( pci ); 00219 DBG ( "Removed PCI device %02x:%02x.%x\n", pci->bus, 00220 PCI_SLOT ( pci->devfn ), PCI_FUNC ( pci->devfn ) ); 00221 }
| static int pcibus_probe | ( | struct root_device * | rootdev | ) | [static] |
Probe PCI root bus.
| rootdev | PCI bus root device |
Definition at line 231 of file pci.c.
References pci_device::bus, device_description::bus_type, BUS_TYPE_PCI, device::children, device_description::class, pci_device::class, device::desc, root_device::dev, pci_device::dev, pci_device::devfn, device_description::device, pci_device::device, ENOMEM, free(), INIT_LIST_HEAD, pci_device::ioaddr, device_description::ioaddr, device_description::irq, pci_device::irq, list_add, list_del, device_description::location, malloc(), memset(), device::name, NULL, device::parent, PCI_BUSDEVFN, PCI_FUNC, PCI_HEADER_TYPE, PCI_INTERRUPT_LINE, pci_max_bus(), pci_probe(), pci_read_bases(), pci_read_config_byte(), pci_read_config_dword(), PCI_REVISION, PCI_SLOT, PCI_VENDOR_ID, pcibus_remove(), device::siblings, snprintf(), device_description::vendor, and pci_device::vendor.
00231 { 00232 struct pci_device *pci = NULL; 00233 unsigned int max_bus; 00234 unsigned int bus; 00235 unsigned int devfn; 00236 uint8_t hdrtype = 0; 00237 uint32_t tmp; 00238 int rc; 00239 00240 max_bus = pci_max_bus(); 00241 for ( bus = 0 ; bus <= max_bus ; bus++ ) { 00242 for ( devfn = 0 ; devfn <= 0xff ; devfn++ ) { 00243 00244 /* Allocate struct pci_device */ 00245 if ( ! pci ) 00246 pci = malloc ( sizeof ( *pci ) ); 00247 if ( ! pci ) { 00248 rc = -ENOMEM; 00249 goto err; 00250 } 00251 memset ( pci, 0, sizeof ( *pci ) ); 00252 pci->bus = bus; 00253 pci->devfn = devfn; 00254 00255 /* Skip all but the first function on 00256 * non-multifunction cards 00257 */ 00258 if ( PCI_FUNC ( devfn ) == 0 ) { 00259 pci_read_config_byte ( pci, PCI_HEADER_TYPE, 00260 &hdrtype ); 00261 } else if ( ! ( hdrtype & 0x80 ) ) { 00262 continue; 00263 } 00264 00265 /* Check for physical device presence */ 00266 pci_read_config_dword ( pci, PCI_VENDOR_ID, &tmp ); 00267 if ( ( tmp == 0xffffffff ) || ( tmp == 0 ) ) 00268 continue; 00269 00270 /* Populate struct pci_device */ 00271 pci->vendor = ( tmp & 0xffff ); 00272 pci->device = ( tmp >> 16 ); 00273 pci_read_config_dword ( pci, PCI_REVISION, &tmp ); 00274 pci->class = ( tmp >> 8 ); 00275 pci_read_config_byte ( pci, PCI_INTERRUPT_LINE, 00276 &pci->irq ); 00277 pci_read_bases ( pci ); 00278 00279 /* Add to device hierarchy */ 00280 snprintf ( pci->dev.name, sizeof ( pci->dev.name ), 00281 "PCI%02x:%02x.%x", bus, 00282 PCI_SLOT ( devfn ), PCI_FUNC ( devfn ) ); 00283 pci->dev.desc.bus_type = BUS_TYPE_PCI; 00284 pci->dev.desc.location = PCI_BUSDEVFN (bus, devfn); 00285 pci->dev.desc.vendor = pci->vendor; 00286 pci->dev.desc.device = pci->device; 00287 pci->dev.desc.class = pci->class; 00288 pci->dev.desc.ioaddr = pci->ioaddr; 00289 pci->dev.desc.irq = pci->irq; 00290 pci->dev.parent = &rootdev->dev; 00291 list_add ( &pci->dev.siblings, &rootdev->dev.children); 00292 INIT_LIST_HEAD ( &pci->dev.children ); 00293 00294 /* Look for a driver */ 00295 if ( pci_probe ( pci ) == 0 ) { 00296 /* pcidev registered, we can drop our ref */ 00297 pci = NULL; 00298 } else { 00299 /* Not registered; re-use struct pci_device */ 00300 list_del ( &pci->dev.siblings ); 00301 } 00302 } 00303 } 00304 00305 free ( pci ); 00306 return 0; 00307 00308 err: 00309 free ( pci ); 00310 pcibus_remove ( rootdev ); 00311 return rc; 00312 }
struct root_driver pci_root_driver [static] |
| struct root_device pci_root_device __root_device |
1.5.7.1