Back to index

lshw  02.16
Classes | Defines | Typedefs | Enumerations | Functions | Variables
pci.cc File Reference
#include "version.h"
#include "config.h"
#include "pci.h"
#include "osutils.h"
#include "options.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>

Go to the source code of this file.

Classes

struct  pci_dev
struct  pci_entry

Defines

#define PROC_BUS_PCI   "/proc/bus/pci"
#define SYS_BUS_PCI   "/sys/bus/pci"
#define PCIID_PATH   DATADIR"/pci.ids:/usr/share/lshw/pci.ids:/usr/local/share/pci.ids:/usr/share/pci.ids:/etc/pci.ids:/usr/share/hwdata/pci.ids:/usr/share/misc/pci.ids"
#define PCI_CLASS_REVISION   0x08 /* High 24 bits are class, low 8 revision */
#define PCI_VENDOR_ID   0x00 /* 16 bits */
#define PCI_DEVICE_ID   0x02 /* 16 bits */
#define PCI_COMMAND   0x04 /* 16 bits */
#define PCI_REVISION_ID   0x08 /* Revision ID */
#define PCI_CLASS_PROG   0x09 /* Reg. Level Programming Interface */
#define PCI_CLASS_DEVICE   0x0a /* Device class */
#define PCI_HEADER_TYPE   0x0e /* 8 bits */
#define PCI_HEADER_TYPE_NORMAL   0
#define PCI_HEADER_TYPE_BRIDGE   1
#define PCI_HEADER_TYPE_CARDBUS   2
#define PCI_PRIMARY_BUS   0x18 /* Primary bus number */
#define PCI_SECONDARY_BUS   0x19 /* Secondary bus number */
#define PCI_STATUS   0x06 /* 16 bits */
#define PCI_LATENCY_TIMER   0x0d /* 8 bits */
#define PCI_SEC_LATENCY_TIMER   0x1b /* Latency timer for secondary interface */
#define PCI_CB_LATENCY_TIMER   0x1b /* CardBus latency timer */
#define PCI_STATUS_66MHZ   0x20 /* Support 66 Mhz PCI 2.1 bus */
#define PCI_STATUS_CAP_LIST   0x10 /* Support Capability List */
#define PCI_COMMAND_IO   0x1 /* Enable response in I/O space */
#define PCI_COMMAND_MEMORY   0x2 /* Enable response in Memory space */
#define PCI_COMMAND_MASTER   0x4 /* Enable bus mastering */
#define PCI_COMMAND_SPECIAL   0x8 /* Enable response to special cycles */
#define PCI_COMMAND_INVALIDATE   0x10 /* Use memory write and invalidate */
#define PCI_COMMAND_VGA_PALETTE   0x20 /* Enable palette snooping */
#define PCI_COMMAND_PARITY   0x40 /* Enable parity checking */
#define PCI_COMMAND_WAIT   0x80 /* Enable address/data stepping */
#define PCI_COMMAND_SERR   0x100 /* Enable SERR */
#define PCI_COMMAND_FAST_BACK   0x200 /* Enable back-to-back writes */
#define PCI_MIN_GNT   0x3e /* 8 bits */
#define PCI_MAX_LAT   0x3f /* 8 bits */
#define PCI_CAPABILITY_LIST   0x34 /* Offset of first capability list entry */
#define PCI_CAP_LIST_ID   0 /* Capability ID */
#define PCI_CAP_ID_PM   0x01 /* Power Management */
#define PCI_CAP_ID_AGP   0x02 /* Accelerated Graphics Port */
#define PCI_CAP_ID_VPD   0x03 /* Vital Product Data */
#define PCI_CAP_ID_SLOTID   0x04 /* Slot Identification */
#define PCI_CAP_ID_MSI   0x05 /* Message Signalled Interrupts */
#define PCI_CAP_ID_CHSWP   0x06 /* CompactPCI HotSwap */
#define PCI_CAP_ID_PCIX   0x07 /* PCI-X */
#define PCI_CAP_ID_HT   0x08 /* HyperTransport */
#define PCI_CAP_ID_VNDR   0x09 /* Vendor specific */
#define PCI_CAP_ID_DBG   0x0A /* Debug port */
#define PCI_CAP_ID_CCRC   0x0B /* CompactPCI Central Resource Control */
#define PCI_CAP_ID_AGP3   0x0E /* AGP 8x */
#define PCI_CAP_ID_EXP   0x10 /* PCI Express */
#define PCI_CAP_ID_MSIX   0x11 /* MSI-X */
#define PCI_CAP_LIST_NEXT   1 /* Next capability in the list */
#define PCI_CAP_FLAGS   2 /* Capability defined flags (16 bits) */
#define PCI_CAP_SIZEOF   4
#define PCI_FIND_CAP_TTL   48
#define PCI_SID_ESR   2 /* Expansion Slot Register */
#define PCI_SID_ESR_NSLOTS   0x1f /* Number of expansion slots available */
#define PCI_DEVFN(slot, func)   ((((slot) & 0x1f) << 3) | ((func) & 0x07))
#define PCI_SLOT(devfn)   (((devfn) >> 3) & 0x1f)
#define PCI_FUNC(devfn)   ((devfn) & 0x07)
#define PCI_CLASS_NOT_DEFINED   0x0000
#define PCI_CLASS_NOT_DEFINED_VGA   0x0001
#define PCI_BASE_CLASS_STORAGE   0x01
#define PCI_CLASS_STORAGE_SCSI   0x0100
#define PCI_CLASS_STORAGE_IDE   0x0101
#define PCI_CLASS_STORAGE_FLOPPY   0x0102
#define PCI_CLASS_STORAGE_IPI   0x0103
#define PCI_CLASS_STORAGE_RAID   0x0104
#define PCI_CLASS_STORAGE_OTHER   0x0180
#define PCI_BASE_CLASS_NETWORK   0x02
#define PCI_CLASS_NETWORK_ETHERNET   0x0200
#define PCI_CLASS_NETWORK_TOKEN_RING   0x0201
#define PCI_CLASS_NETWORK_FDDI   0x0202
#define PCI_CLASS_NETWORK_ATM   0x0203
#define PCI_CLASS_NETWORK_OTHER   0x0280
#define PCI_BASE_CLASS_DISPLAY   0x03
#define PCI_CLASS_DISPLAY_VGA   0x0300
#define PCI_CLASS_DISPLAY_XGA   0x0301
#define PCI_CLASS_DISPLAY_OTHER   0x0380
#define PCI_BASE_CLASS_MULTIMEDIA   0x04
#define PCI_CLASS_MULTIMEDIA_VIDEO   0x0400
#define PCI_CLASS_MULTIMEDIA_AUDIO   0x0401
#define PCI_CLASS_MULTIMEDIA_OTHER   0x0480
#define PCI_BASE_CLASS_MEMORY   0x05
#define PCI_CLASS_MEMORY_RAM   0x0500
#define PCI_CLASS_MEMORY_FLASH   0x0501
#define PCI_CLASS_MEMORY_OTHER   0x0580
#define PCI_BASE_CLASS_BRIDGE   0x06
#define PCI_CLASS_BRIDGE_HOST   0x0600
#define PCI_CLASS_BRIDGE_ISA   0x0601
#define PCI_CLASS_BRIDGE_EISA   0x0602
#define PCI_CLASS_BRIDGE_MC   0x0603
#define PCI_CLASS_BRIDGE_PCI   0x0604
#define PCI_CLASS_BRIDGE_PCMCIA   0x0605
#define PCI_CLASS_BRIDGE_NUBUS   0x0606
#define PCI_CLASS_BRIDGE_CARDBUS   0x0607
#define PCI_CLASS_BRIDGE_OTHER   0x0680
#define PCI_BASE_CLASS_COMMUNICATION   0x07
#define PCI_CLASS_COMMUNICATION_SERIAL   0x0700
#define PCI_CLASS_COMMUNICATION_PARALLEL   0x0701
#define PCI_CLASS_COMMUNICATION_MODEM   0x0703
#define PCI_CLASS_COMMUNICATION_OTHER   0x0780
#define PCI_BASE_CLASS_SYSTEM   0x08
#define PCI_CLASS_SYSTEM_PIC   0x0800
#define PCI_CLASS_SYSTEM_DMA   0x0801
#define PCI_CLASS_SYSTEM_TIMER   0x0802
#define PCI_CLASS_SYSTEM_RTC   0x0803
#define PCI_CLASS_SYSTEM_OTHER   0x0880
#define PCI_BASE_CLASS_INPUT   0x09
#define PCI_CLASS_INPUT_KEYBOARD   0x0900
#define PCI_CLASS_INPUT_PEN   0x0901
#define PCI_CLASS_INPUT_MOUSE   0x0902
#define PCI_CLASS_INPUT_OTHER   0x0980
#define PCI_BASE_CLASS_DOCKING   0x0a
#define PCI_CLASS_DOCKING_GENERIC   0x0a00
#define PCI_CLASS_DOCKING_OTHER   0x0a01
#define PCI_BASE_CLASS_PROCESSOR   0x0b
#define PCI_CLASS_PROCESSOR_386   0x0b00
#define PCI_CLASS_PROCESSOR_486   0x0b01
#define PCI_CLASS_PROCESSOR_PENTIUM   0x0b02
#define PCI_CLASS_PROCESSOR_ALPHA   0x0b10
#define PCI_CLASS_PROCESSOR_POWERPC   0x0b20
#define PCI_CLASS_PROCESSOR_CO   0x0b40
#define PCI_BASE_CLASS_SERIAL   0x0c
#define PCI_CLASS_SERIAL_FIREWIRE   0x0c00
#define PCI_CLASS_SERIAL_ACCESS   0x0c01
#define PCI_CLASS_SERIAL_SSA   0x0c02
#define PCI_CLASS_SERIAL_USB   0x0c03
#define PCI_CLASS_SERIAL_FIBER   0x0c04
#define PCI_CLASS_OTHERS   0xff
#define PCI_ADDR_MEM_MASK   (~(pciaddr_t) 0xf)
#define PCI_BASE_ADDRESS_0   0x10 /* 32 bits */
#define PCI_BASE_ADDRESS_SPACE   0x01 /* 0 = memory, 1 = I/O */
#define PCI_BASE_ADDRESS_SPACE_IO   0x01
#define PCI_BASE_ADDRESS_SPACE_MEMORY   0x00
#define PCI_BASE_ADDRESS_MEM_TYPE_MASK   0x06
#define PCI_BASE_ADDRESS_MEM_TYPE_32   0x00 /* 32 bit address */
#define PCI_BASE_ADDRESS_MEM_TYPE_1M   0x02 /* Below 1M [obsolete] */
#define PCI_BASE_ADDRESS_MEM_TYPE_64   0x04 /* 64 bit address */
#define PCI_BASE_ADDRESS_MEM_PREFETCH   0x08 /* prefetchable? */
#define PCI_BASE_ADDRESS_MEM_MASK   (~0x0fUL)
#define PCI_BASE_ADDRESS_IO_MASK   (~0x03UL)
#define PCI_SUBSYSTEM_VENDOR_ID   0x2c
#define PCI_SUBSYSTEM_ID   0x2e
#define PCI_CB_SUBSYSTEM_VENDOR_ID   0x40
#define PCI_CB_SUBSYSTEM_ID   0x42

Typedefs

typedef unsigned long long pciaddr_t

Enumerations

enum  catalog {
  pcidevice, pcisubdevice, pcisubsystem, pciclass,
  pcisubclass, pcivendor, pcisubvendor, pciprogif
}

Functions

 __ID ("@(#) $Id: pci.cc 2433 2012-01-10 22:01:30Z lyonel $")
static bool find_best_match (vector< pci_entry > &list, pci_entry &result, long u1=-1, long u2=-1, long u3=-1, long u4=-1)
static const char * get_class_name (unsigned int c)
static bool parse_pcidb (vector< string > &list)
static bool load_pcidb ()
static string get_class_description (long c, long pi=-1)
static string get_device_description (long u1, long u2=-1, long u3=-1, long u4=-1)
static u_int32_t get_conf_long (struct pci_dev d, unsigned int pos)
static u_int16_t get_conf_word (struct pci_dev d, unsigned int pos)
static u_int8_t get_conf_byte (struct pci_dev d, unsigned int pos)
static string pci_bushandle (u_int8_t bus, u_int16_t domain=0)
static string pci_handle (u_int16_t bus, u_int8_t dev, u_int8_t fct, u_int16_t domain=0)
static bool scan_resources (hwNode &n, struct pci_dev &d)
static bool scan_capabilities (hwNode &n, struct pci_dev &d)
static void addHints (hwNode &n, long _vendor, long _device, long _subvendor, long _subdevice, long _class)
static hwNodescan_pci_dev (struct pci_dev &d, hwNode &n)
bool scan_pci_legacy (hwNode &n)
bool scan_pci (hwNode &n)

Variables

bool pcidb_loaded = false
static vector< pci_entrypci_devices
static vector< pci_entrypci_classes

Class Documentation

struct pci_dev

Definition at line 215 of file pci.cc.

Class Members
pciaddr_t base_addr
u_int16_t bus
u_int8_t config
u_int8_t dev
u_int16_t device_id
u_int16_t domain
u_int8_t func
unsigned int irq
pciaddr_t rom_base_addr
pciaddr_t rom_size
pciaddr_t size
u_int16_t vendor_id

Define Documentation

#define PCI_ADDR_MEM_MASK   (~(pciaddr_t) 0xf)

Definition at line 178 of file pci.cc.

#define PCI_BASE_ADDRESS_0   0x10 /* 32 bits */

Definition at line 179 of file pci.cc.

#define PCI_BASE_ADDRESS_IO_MASK   (~0x03UL)

Definition at line 189 of file pci.cc.

#define PCI_BASE_ADDRESS_MEM_MASK   (~0x0fUL)

Definition at line 188 of file pci.cc.

#define PCI_BASE_ADDRESS_MEM_PREFETCH   0x08 /* prefetchable? */

Definition at line 187 of file pci.cc.

#define PCI_BASE_ADDRESS_MEM_TYPE_1M   0x02 /* Below 1M [obsolete] */

Definition at line 185 of file pci.cc.

#define PCI_BASE_ADDRESS_MEM_TYPE_32   0x00 /* 32 bit address */

Definition at line 184 of file pci.cc.

#define PCI_BASE_ADDRESS_MEM_TYPE_64   0x04 /* 64 bit address */

Definition at line 186 of file pci.cc.

#define PCI_BASE_ADDRESS_MEM_TYPE_MASK   0x06

Definition at line 183 of file pci.cc.

#define PCI_BASE_ADDRESS_SPACE   0x01 /* 0 = memory, 1 = I/O */

Definition at line 180 of file pci.cc.

#define PCI_BASE_ADDRESS_SPACE_IO   0x01

Definition at line 181 of file pci.cc.

#define PCI_BASE_ADDRESS_SPACE_MEMORY   0x00

Definition at line 182 of file pci.cc.

#define PCI_BASE_CLASS_BRIDGE   0x06

Definition at line 127 of file pci.cc.

#define PCI_BASE_CLASS_COMMUNICATION   0x07

Definition at line 138 of file pci.cc.

#define PCI_BASE_CLASS_DISPLAY   0x03

Definition at line 112 of file pci.cc.

#define PCI_BASE_CLASS_DOCKING   0x0a

Definition at line 157 of file pci.cc.

#define PCI_BASE_CLASS_INPUT   0x09

Definition at line 151 of file pci.cc.

#define PCI_BASE_CLASS_MEMORY   0x05

Definition at line 122 of file pci.cc.

#define PCI_BASE_CLASS_MULTIMEDIA   0x04

Definition at line 117 of file pci.cc.

#define PCI_BASE_CLASS_NETWORK   0x02

Definition at line 105 of file pci.cc.

#define PCI_BASE_CLASS_PROCESSOR   0x0b

Definition at line 161 of file pci.cc.

#define PCI_BASE_CLASS_SERIAL   0x0c

Definition at line 169 of file pci.cc.

#define PCI_BASE_CLASS_STORAGE   0x01

Definition at line 97 of file pci.cc.

#define PCI_BASE_CLASS_SYSTEM   0x08

Definition at line 144 of file pci.cc.

#define PCI_CAP_FLAGS   2 /* Capability defined flags (16 bits) */

Definition at line 72 of file pci.cc.

#define PCI_CAP_ID_AGP   0x02 /* Accelerated Graphics Port */

Definition at line 58 of file pci.cc.

#define PCI_CAP_ID_AGP3   0x0E /* AGP 8x */

Definition at line 68 of file pci.cc.

#define PCI_CAP_ID_CCRC   0x0B /* CompactPCI Central Resource Control */

Definition at line 67 of file pci.cc.

#define PCI_CAP_ID_CHSWP   0x06 /* CompactPCI HotSwap */

Definition at line 62 of file pci.cc.

#define PCI_CAP_ID_DBG   0x0A /* Debug port */

Definition at line 66 of file pci.cc.

#define PCI_CAP_ID_EXP   0x10 /* PCI Express */

Definition at line 69 of file pci.cc.

#define PCI_CAP_ID_HT   0x08 /* HyperTransport */

Definition at line 64 of file pci.cc.

#define PCI_CAP_ID_MSI   0x05 /* Message Signalled Interrupts */

Definition at line 61 of file pci.cc.

#define PCI_CAP_ID_MSIX   0x11 /* MSI-X */

Definition at line 70 of file pci.cc.

#define PCI_CAP_ID_PCIX   0x07 /* PCI-X */

Definition at line 63 of file pci.cc.

#define PCI_CAP_ID_PM   0x01 /* Power Management */

Definition at line 57 of file pci.cc.

#define PCI_CAP_ID_SLOTID   0x04 /* Slot Identification */

Definition at line 60 of file pci.cc.

#define PCI_CAP_ID_VNDR   0x09 /* Vendor specific */

Definition at line 65 of file pci.cc.

#define PCI_CAP_ID_VPD   0x03 /* Vital Product Data */

Definition at line 59 of file pci.cc.

#define PCI_CAP_LIST_ID   0 /* Capability ID */

Definition at line 56 of file pci.cc.

#define PCI_CAP_LIST_NEXT   1 /* Next capability in the list */

Definition at line 71 of file pci.cc.

#define PCI_CAP_SIZEOF   4

Definition at line 73 of file pci.cc.

#define PCI_CAPABILITY_LIST   0x34 /* Offset of first capability list entry */

Definition at line 55 of file pci.cc.

#define PCI_CB_LATENCY_TIMER   0x1b /* CardBus latency timer */

Definition at line 38 of file pci.cc.

#define PCI_CB_SUBSYSTEM_ID   0x42

Definition at line 195 of file pci.cc.

#define PCI_CB_SUBSYSTEM_VENDOR_ID   0x40

Definition at line 194 of file pci.cc.

#define PCI_CLASS_BRIDGE_CARDBUS   0x0607

Definition at line 135 of file pci.cc.

#define PCI_CLASS_BRIDGE_EISA   0x0602

Definition at line 130 of file pci.cc.

#define PCI_CLASS_BRIDGE_HOST   0x0600

Definition at line 128 of file pci.cc.

#define PCI_CLASS_BRIDGE_ISA   0x0601

Definition at line 129 of file pci.cc.

#define PCI_CLASS_BRIDGE_MC   0x0603

Definition at line 131 of file pci.cc.

#define PCI_CLASS_BRIDGE_NUBUS   0x0606

Definition at line 134 of file pci.cc.

#define PCI_CLASS_BRIDGE_OTHER   0x0680

Definition at line 136 of file pci.cc.

#define PCI_CLASS_BRIDGE_PCI   0x0604

Definition at line 132 of file pci.cc.

#define PCI_CLASS_BRIDGE_PCMCIA   0x0605

Definition at line 133 of file pci.cc.

#define PCI_CLASS_COMMUNICATION_MODEM   0x0703

Definition at line 141 of file pci.cc.

#define PCI_CLASS_COMMUNICATION_OTHER   0x0780

Definition at line 142 of file pci.cc.

#define PCI_CLASS_COMMUNICATION_PARALLEL   0x0701

Definition at line 140 of file pci.cc.

#define PCI_CLASS_COMMUNICATION_SERIAL   0x0700

Definition at line 139 of file pci.cc.

#define PCI_CLASS_DEVICE   0x0a /* Device class */

Definition at line 28 of file pci.cc.

#define PCI_CLASS_DISPLAY_OTHER   0x0380

Definition at line 115 of file pci.cc.

#define PCI_CLASS_DISPLAY_VGA   0x0300

Definition at line 113 of file pci.cc.

#define PCI_CLASS_DISPLAY_XGA   0x0301

Definition at line 114 of file pci.cc.

#define PCI_CLASS_DOCKING_GENERIC   0x0a00

Definition at line 158 of file pci.cc.

#define PCI_CLASS_DOCKING_OTHER   0x0a01

Definition at line 159 of file pci.cc.

#define PCI_CLASS_INPUT_KEYBOARD   0x0900

Definition at line 152 of file pci.cc.

#define PCI_CLASS_INPUT_MOUSE   0x0902

Definition at line 154 of file pci.cc.

#define PCI_CLASS_INPUT_OTHER   0x0980

Definition at line 155 of file pci.cc.

#define PCI_CLASS_INPUT_PEN   0x0901

Definition at line 153 of file pci.cc.

#define PCI_CLASS_MEMORY_FLASH   0x0501

Definition at line 124 of file pci.cc.

#define PCI_CLASS_MEMORY_OTHER   0x0580

Definition at line 125 of file pci.cc.

#define PCI_CLASS_MEMORY_RAM   0x0500

Definition at line 123 of file pci.cc.

#define PCI_CLASS_MULTIMEDIA_AUDIO   0x0401

Definition at line 119 of file pci.cc.

#define PCI_CLASS_MULTIMEDIA_OTHER   0x0480

Definition at line 120 of file pci.cc.

#define PCI_CLASS_MULTIMEDIA_VIDEO   0x0400

Definition at line 118 of file pci.cc.

#define PCI_CLASS_NETWORK_ATM   0x0203

Definition at line 109 of file pci.cc.

#define PCI_CLASS_NETWORK_ETHERNET   0x0200

Definition at line 106 of file pci.cc.

#define PCI_CLASS_NETWORK_FDDI   0x0202

Definition at line 108 of file pci.cc.

#define PCI_CLASS_NETWORK_OTHER   0x0280

Definition at line 110 of file pci.cc.

#define PCI_CLASS_NETWORK_TOKEN_RING   0x0201

Definition at line 107 of file pci.cc.

#define PCI_CLASS_NOT_DEFINED   0x0000

Definition at line 94 of file pci.cc.

#define PCI_CLASS_NOT_DEFINED_VGA   0x0001

Definition at line 95 of file pci.cc.

#define PCI_CLASS_OTHERS   0xff

Definition at line 176 of file pci.cc.

#define PCI_CLASS_PROCESSOR_386   0x0b00

Definition at line 162 of file pci.cc.

#define PCI_CLASS_PROCESSOR_486   0x0b01

Definition at line 163 of file pci.cc.

#define PCI_CLASS_PROCESSOR_ALPHA   0x0b10

Definition at line 165 of file pci.cc.

#define PCI_CLASS_PROCESSOR_CO   0x0b40

Definition at line 167 of file pci.cc.

#define PCI_CLASS_PROCESSOR_PENTIUM   0x0b02

Definition at line 164 of file pci.cc.

#define PCI_CLASS_PROCESSOR_POWERPC   0x0b20

Definition at line 166 of file pci.cc.

#define PCI_CLASS_PROG   0x09 /* Reg. Level Programming Interface */

Definition at line 27 of file pci.cc.

#define PCI_CLASS_REVISION   0x08 /* High 24 bits are class, low 8 revision */

Definition at line 22 of file pci.cc.

#define PCI_CLASS_SERIAL_ACCESS   0x0c01

Definition at line 171 of file pci.cc.

#define PCI_CLASS_SERIAL_FIBER   0x0c04

Definition at line 174 of file pci.cc.

#define PCI_CLASS_SERIAL_FIREWIRE   0x0c00

Definition at line 170 of file pci.cc.

#define PCI_CLASS_SERIAL_SSA   0x0c02

Definition at line 172 of file pci.cc.

#define PCI_CLASS_SERIAL_USB   0x0c03

Definition at line 173 of file pci.cc.

#define PCI_CLASS_STORAGE_FLOPPY   0x0102

Definition at line 100 of file pci.cc.

#define PCI_CLASS_STORAGE_IDE   0x0101

Definition at line 99 of file pci.cc.

#define PCI_CLASS_STORAGE_IPI   0x0103

Definition at line 101 of file pci.cc.

#define PCI_CLASS_STORAGE_OTHER   0x0180

Definition at line 103 of file pci.cc.

#define PCI_CLASS_STORAGE_RAID   0x0104

Definition at line 102 of file pci.cc.

#define PCI_CLASS_STORAGE_SCSI   0x0100

Definition at line 98 of file pci.cc.

#define PCI_CLASS_SYSTEM_DMA   0x0801

Definition at line 146 of file pci.cc.

#define PCI_CLASS_SYSTEM_OTHER   0x0880

Definition at line 149 of file pci.cc.

#define PCI_CLASS_SYSTEM_PIC   0x0800

Definition at line 145 of file pci.cc.

#define PCI_CLASS_SYSTEM_RTC   0x0803

Definition at line 148 of file pci.cc.

#define PCI_CLASS_SYSTEM_TIMER   0x0802

Definition at line 147 of file pci.cc.

#define PCI_COMMAND   0x04 /* 16 bits */

Definition at line 25 of file pci.cc.

#define PCI_COMMAND_FAST_BACK   0x200 /* Enable back-to-back writes */

Definition at line 50 of file pci.cc.

#define PCI_COMMAND_INVALIDATE   0x10 /* Use memory write and invalidate */

Definition at line 45 of file pci.cc.

#define PCI_COMMAND_IO   0x1 /* Enable response in I/O space */

Definition at line 41 of file pci.cc.

#define PCI_COMMAND_MASTER   0x4 /* Enable bus mastering */

Definition at line 43 of file pci.cc.

#define PCI_COMMAND_MEMORY   0x2 /* Enable response in Memory space */

Definition at line 42 of file pci.cc.

#define PCI_COMMAND_PARITY   0x40 /* Enable parity checking */

Definition at line 47 of file pci.cc.

#define PCI_COMMAND_SERR   0x100 /* Enable SERR */

Definition at line 49 of file pci.cc.

#define PCI_COMMAND_SPECIAL   0x8 /* Enable response to special cycles */

Definition at line 44 of file pci.cc.

#define PCI_COMMAND_VGA_PALETTE   0x20 /* Enable palette snooping */

Definition at line 46 of file pci.cc.

#define PCI_COMMAND_WAIT   0x80 /* Enable address/data stepping */

Definition at line 48 of file pci.cc.

#define PCI_DEVFN (   slot,
  func 
)    ((((slot) & 0x1f) << 3) | ((func) & 0x07))

Definition at line 88 of file pci.cc.

#define PCI_DEVICE_ID   0x02 /* 16 bits */

Definition at line 24 of file pci.cc.

#define PCI_FIND_CAP_TTL   48

Definition at line 74 of file pci.cc.

#define PCI_FUNC (   devfn)    ((devfn) & 0x07)

Definition at line 90 of file pci.cc.

#define PCI_HEADER_TYPE   0x0e /* 8 bits */

Definition at line 29 of file pci.cc.

#define PCI_HEADER_TYPE_BRIDGE   1

Definition at line 31 of file pci.cc.

#define PCI_HEADER_TYPE_CARDBUS   2

Definition at line 32 of file pci.cc.

#define PCI_HEADER_TYPE_NORMAL   0

Definition at line 30 of file pci.cc.

#define PCI_LATENCY_TIMER   0x0d /* 8 bits */

Definition at line 36 of file pci.cc.

#define PCI_MAX_LAT   0x3f /* 8 bits */

Definition at line 53 of file pci.cc.

#define PCI_MIN_GNT   0x3e /* 8 bits */

Definition at line 52 of file pci.cc.

#define PCI_PRIMARY_BUS   0x18 /* Primary bus number */

Definition at line 33 of file pci.cc.

#define PCI_REVISION_ID   0x08 /* Revision ID */

Definition at line 26 of file pci.cc.

#define PCI_SEC_LATENCY_TIMER   0x1b /* Latency timer for secondary interface */

Definition at line 37 of file pci.cc.

#define PCI_SECONDARY_BUS   0x19 /* Secondary bus number */

Definition at line 34 of file pci.cc.

#define PCI_SID_ESR   2 /* Expansion Slot Register */

Definition at line 76 of file pci.cc.

#define PCI_SID_ESR_NSLOTS   0x1f /* Number of expansion slots available */

Definition at line 77 of file pci.cc.

#define PCI_SLOT (   devfn)    (((devfn) >> 3) & 0x1f)

Definition at line 89 of file pci.cc.

#define PCI_STATUS   0x06 /* 16 bits */

Definition at line 35 of file pci.cc.

#define PCI_STATUS_66MHZ   0x20 /* Support 66 Mhz PCI 2.1 bus */

Definition at line 39 of file pci.cc.

#define PCI_STATUS_CAP_LIST   0x10 /* Support Capability List */

Definition at line 40 of file pci.cc.

#define PCI_SUBSYSTEM_ID   0x2e

Definition at line 192 of file pci.cc.

#define PCI_SUBSYSTEM_VENDOR_ID   0x2c

Definition at line 191 of file pci.cc.

#define PCI_VENDOR_ID   0x00 /* 16 bits */

Definition at line 23 of file pci.cc.

#define PCIID_PATH   DATADIR"/pci.ids:/usr/share/lshw/pci.ids:/usr/local/share/pci.ids:/usr/share/pci.ids:/etc/pci.ids:/usr/share/hwdata/pci.ids:/usr/share/misc/pci.ids"

Definition at line 20 of file pci.cc.

#define PROC_BUS_PCI   "/proc/bus/pci"

Definition at line 18 of file pci.cc.

#define SYS_BUS_PCI   "/sys/bus/pci"

Definition at line 19 of file pci.cc.


Typedef Documentation

typedef unsigned long long pciaddr_t

Definition at line 199 of file pci.cc.


Enumeration Type Documentation

enum catalog
Enumerator:
pcidevice 
pcisubdevice 
pcisubsystem 
pciclass 
pcisubclass 
pcivendor 
pcisubvendor 
pciprogif 

Definition at line 200 of file pci.cc.


Function Documentation

__ID ( "@(#) $Id: pci.cc 2433 2012-01-10 22:01:30Z lyonel $"  )
static void addHints ( hwNode n,
long  _vendor,
long  _device,
long  _subvendor,
long  _subdevice,
long  _class 
) [static]

Definition at line 739 of file pci.cc.

{
  n.addHint("pci.vendor", _vendor);
  n.addHint("pci.device", _device);
  if(_subvendor && (_subvendor != 0xffff))
  {
    n.addHint("pci.subvendor", _subvendor);
    n.addHint("pci.subdevice", _subdevice);
  }
  n.addHint("pci.class", _class);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool find_best_match ( vector< pci_entry > &  list,
pci_entry result,
long  u1 = -1,
long  u2 = -1,
long  u3 = -1,
long  u4 = -1 
) [static]

Definition at line 291 of file pci.cc.

{
  int lastmatch = -1;
  unsigned int lastscore = 0;

  for (unsigned int i = 0; i < list.size(); i++)
  {
    unsigned int currentscore = list[i].matches(u1, u2, u3, u4);

    if (currentscore > lastscore)
    {
      lastscore = currentscore;
      lastmatch = i;
    }
  }

  if (lastmatch >= 0)
  {
    result = list[lastmatch];
    return true;
  }

  return false;
}

Here is the caller graph for this function:

static string get_class_description ( long  c,
long  pi = -1 
) [static]

Definition at line 529 of file pci.cc.

{
  pci_entry result("");

  if (find_best_match(pci_classes, result, c >> 8, c & 0xff, pi))
    return result.description;
  else
    return "";
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* get_class_name ( unsigned int  c) [static]

Definition at line 322 of file pci.cc.

{
  switch (c)
  {
    case PCI_CLASS_NOT_DEFINED_VGA:
      return "display";
    case PCI_CLASS_STORAGE_SCSI:
      return "scsi";
    case PCI_CLASS_STORAGE_IDE:
      return "ide";
    case PCI_CLASS_BRIDGE_HOST:
      return "host";
    case PCI_CLASS_BRIDGE_ISA:
      return "isa";
    case PCI_CLASS_BRIDGE_EISA:
      return "eisa";
    case PCI_CLASS_BRIDGE_MC:
      return "mc";
    case PCI_CLASS_BRIDGE_PCI:
      return "pci";
    case PCI_CLASS_BRIDGE_PCMCIA:
      return "pcmcia";
    case PCI_CLASS_BRIDGE_NUBUS:
      return "nubus";
    case PCI_CLASS_BRIDGE_CARDBUS:
      return "pcmcia";
    case PCI_CLASS_SERIAL_FIREWIRE:
      return "firewire";
    case PCI_CLASS_SERIAL_USB:
      return "usb";
    case PCI_CLASS_SERIAL_FIBER:
      return "fiber";
  }

  switch (c >> 8)
  {
    case PCI_BASE_CLASS_STORAGE:
      return "storage";
    case PCI_BASE_CLASS_NETWORK:
      return "network";
    case PCI_BASE_CLASS_DISPLAY:
      return "display";
    case PCI_BASE_CLASS_MULTIMEDIA:
      return "multimedia";
    case PCI_BASE_CLASS_MEMORY:
      return "memory";
    case PCI_BASE_CLASS_BRIDGE:
      return "bridge";
    case PCI_BASE_CLASS_COMMUNICATION:
      return "communication";
    case PCI_BASE_CLASS_SYSTEM:
      return "generic";
    case PCI_BASE_CLASS_INPUT:
      return "input";
    case PCI_BASE_CLASS_DOCKING:
      return "docking";
    case PCI_BASE_CLASS_PROCESSOR:
      return "processor";
    case PCI_BASE_CLASS_SERIAL:
      return "serial";
  }

  return "generic";
}

Here is the caller graph for this function:

static u_int8_t get_conf_byte ( struct pci_dev  d,
unsigned int  pos 
) [static]

Definition at line 576 of file pci.cc.

{
  if (pos > sizeof(d.config))
    return 0;

  return d.config[pos];
}

Here is the caller graph for this function:

static u_int32_t get_conf_long ( struct pci_dev  d,
unsigned int  pos 
) [static]

Definition at line 555 of file pci.cc.

{
  if (pos > sizeof(d.config))
    return 0;

  return d.config[pos] | (d.config[pos + 1] << 8) |
    (d.config[pos + 2] << 16) | (d.config[pos + 3] << 24);
}

Here is the caller graph for this function:

static u_int16_t get_conf_word ( struct pci_dev  d,
unsigned int  pos 
) [static]

Definition at line 566 of file pci.cc.

{
  if (pos > sizeof(d.config))
    return 0;

  return d.config[pos] | (d.config[pos + 1] << 8);
}

Here is the caller graph for this function:

static string get_device_description ( long  u1,
long  u2 = -1,
long  u3 = -1,
long  u4 = -1 
) [static]

Definition at line 541 of file pci.cc.

{
  pci_entry result("");

  if (find_best_match(pci_devices, result, u1, u2, u3, u4))
    return result.description;
  else
    return "";
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool load_pcidb ( ) [static]

Definition at line 509 of file pci.cc.

{
  vector < string > lines;
  vector < string > filenames;

  splitlines(PCIID_PATH, filenames, ':');
  for (int i = filenames.size() - 1; i >= 0; i--)
  {
    lines.clear();
    if (loadfile(filenames[i], lines))
      parse_pcidb(lines);
  }

  if (lines.size() == 0)
    return false;

  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool parse_pcidb ( vector< string > &  list) [static]

Definition at line 388 of file pci.cc.

{
  long u[4];
  string line = "";
  catalog current_catalog = pcivendor;
  unsigned int level = 0;

  memset(u, 0, sizeof(u));

  for (unsigned int i = 0; i < list.size(); i++)
  {
    line = hw::strip(list[i]);

// ignore empty or commented-out lines
    if (line.length() == 0 || line[0] == '#')
      continue;

    level = 0;
    while ((level < list[i].length()) && (list[i][level] == '\t'))
      level++;

    switch (level)
    {
      case 0:
        if ((line[0] == 'C') && (line.length() > 1) && (line[1] == ' '))
        {
          current_catalog = pciclass;
          line = line.substr(2);                  // get rid of 'C '

          if ((line.length() < 3) || (line[2] != ' '))
            return false;
          if (sscanf(line.c_str(), "%lx", &u[0]) != 1)
            return false;
          line = line.substr(3);
          line = hw::strip(line);
        }
        else
        {
          current_catalog = pcivendor;

          if ((line.length() < 5) || (line[4] != ' '))
            return false;
          if (sscanf(line.c_str(), "%lx", &u[0]) != 1)
            return false;
          line = line.substr(5);
          line = hw::strip(line);
        }
        u[1] = u[2] = u[3] = -1;
        break;
      case 1:
        if ((current_catalog == pciclass) || (current_catalog == pcisubclass)
          || (current_catalog == pciprogif))
        {
          current_catalog = pcisubclass;

          if ((line.length() < 3) || (line[2] != ' '))
            return false;
          if (sscanf(line.c_str(), "%lx", &u[1]) != 1)
            return false;
          line = line.substr(3);
          line = hw::strip(line);
        }
        else
        {
          current_catalog = pcidevice;

          if ((line.length() < 5) || (line[4] != ' '))
            return false;
          if (sscanf(line.c_str(), "%lx", &u[1]) != 1)
            return false;
          line = line.substr(5);
          line = hw::strip(line);
        }
        u[2] = u[3] = -1;
        break;
      case 2:
        if ((current_catalog != pcidevice) && (current_catalog != pcisubvendor)
          && (current_catalog != pcisubclass)
          && (current_catalog != pciprogif))
          return false;
        if ((current_catalog == pcisubclass) || (current_catalog == pciprogif))
        {
          current_catalog = pciprogif;
          if ((line.length() < 3) || (line[2] != ' '))
            return false;
          if (sscanf(line.c_str(), "%lx", &u[2]) != 1)
            return false;
          u[3] = -1;
          line = line.substr(2);
          line = hw::strip(line);
        }
        else
        {
          current_catalog = pcisubvendor;
          if ((line.length() < 10) || (line[4] != ' ') || (line[9] != ' '))
            return false;
          if (sscanf(line.c_str(), "%lx%lx", &u[2], &u[3]) != 2)
            return false;
          line = line.substr(9);
          line = hw::strip(line);
        }
        break;
      default:
        return false;
    }

//printf("%04x %04x %04x %04x %s\n", u[0], u[1], u[2], u[3], line.c_str());
    if ((current_catalog == pciclass) ||
      (current_catalog == pcisubclass) || (current_catalog == pciprogif))
    {
      pci_classes.push_back(pci_entry(line, u[0], u[1], u[2], u[3]));
    }
    else
    {
      pci_devices.push_back(pci_entry(line, u[0], u[1], u[2], u[3]));
    }
  }
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static string pci_bushandle ( u_int8_t  bus,
u_int16_t  domain = 0 
) [static]

Definition at line 586 of file pci.cc.

{
  char buffer[20];

  if(domain == (u_int16_t)(-1))
    snprintf(buffer, sizeof(buffer), "%02x", bus);
  else
    snprintf(buffer, sizeof(buffer), "%04x:%02x", domain, bus);

  return "PCIBUS:" + string(buffer);
}

Here is the caller graph for this function:

static string pci_handle ( u_int16_t  bus,
u_int8_t  dev,
u_int8_t  fct,
u_int16_t  domain = 0 
) [static]

Definition at line 599 of file pci.cc.

{
  char buffer[30];

  if(domain == (u_int16_t)(-1))
    snprintf(buffer, sizeof(buffer), "PCI:%02x:%02x.%x", bus, dev, fct);
  else
    snprintf(buffer, sizeof(buffer), "PCI:%04x:%02x:%02x.%x", domain, bus, dev, fct);

  return string(buffer);
}

Here is the caller graph for this function:

static bool scan_capabilities ( hwNode n,
struct pci_dev d 
) [static]

Definition at line 669 of file pci.cc.

{
  unsigned int where = get_conf_byte(d, PCI_CAPABILITY_LIST) & ~3;
  string buffer;
  unsigned int ttl = PCI_FIND_CAP_TTL;

  while(where && ttl--)
  {
    unsigned int id, next, cap;

    id = get_conf_byte(d, where + PCI_CAP_LIST_ID);
    next = get_conf_byte(d, where + PCI_CAP_LIST_NEXT) & ~3;
    cap = get_conf_word(d, where + PCI_CAP_FLAGS);

    if(!id || id == 0xff)
      return false;

    switch(id)
    {
      case PCI_CAP_ID_PM:
        n.addCapability("pm", "Power Management");
        break;
      case PCI_CAP_ID_AGP:
        n.addCapability("agp", "AGP");
        buffer = hw::asString((cap >> 4) & 0x0f) + "." + hw::asString(cap & 0x0f);
        n.addCapability("agp-"+buffer, "AGP "+buffer);
        break;
      case PCI_CAP_ID_VPD:
        n.addCapability("vpd", "Vital Product Data");
        break;
      case PCI_CAP_ID_SLOTID:
        n.addCapability("slotid", "Slot Identification");
        n.setSlot(hw::asString(cap & PCI_SID_ESR_NSLOTS)+", chassis "+hw::asString(cap>>8));
        break;
      case PCI_CAP_ID_MSI:
        n.addCapability("msi", "Message Signalled Interrupts");
        break;
      case PCI_CAP_ID_CHSWP:
        n.addCapability("hotswap", "Hot-swap");
        break;
      case PCI_CAP_ID_PCIX:
        n.addCapability("pcix", "PCI-X");
        break;
      case PCI_CAP_ID_HT:
        n.addCapability("ht", "HyperTransport");
        break;
      case PCI_CAP_ID_DBG:
        n.addCapability("debug", "Debug port");
        break;
      case PCI_CAP_ID_CCRC:
        n.addCapability("ccrc", "CompactPCI Central Resource Control");
        break;
      case PCI_CAP_ID_AGP3:
        n.addCapability("agp8x", "AGP 8x");
        break;
      case PCI_CAP_ID_EXP:
        n.addCapability("pciexpress", _("PCI Express"));
        break;
      case PCI_CAP_ID_MSIX:
        n.addCapability("msix", "MSI-X");
        break;
    }

    where = next;
  }

  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool scan_pci ( hwNode n)

Definition at line 1083 of file pci.cc.

{
  bool result = false;
  dirent **devices = NULL;
  int count = 0;
  hwNode *core = n.getChild("core");

  if (!core)
  {
    n.addChild(hwNode("core", hw::bus));
    core = n.getChild("core");
  }

  pcidb_loaded = load_pcidb();

  if(!pushd(SYS_BUS_PCI"/devices"))
    return false;
  count = scandir(".", &devices, selectlink, alphasort);
  if(count>=0)
  {
    int i = 0;
    for(i=0; i<count; i++)
    if(matches(devices[i]->d_name, "^[[:xdigit:]]+:[[:xdigit:]]+:[[:xdigit:]]+\\.[[:xdigit:]]+$"))
    {
      string devicepath = string(devices[i]->d_name)+"/config";
      struct pci_dev d;
      int fd = open(devicepath.c_str(), O_RDONLY);
      if (fd >= 0)
      {
        memset(&d, 0, sizeof(d));
        if(read(fd, d.config, 64) == 64)
        {
          if(read(fd, d.config+64, sizeof(d.config)-64) != sizeof(d.config)-64)
            memset(d.config+64, 0, sizeof(d.config)-64);
        }
        close(fd);
      }

      sscanf(devices[i]->d_name, "%hx:%hx:%hhx.%hhx", &d.domain, &d.bus, &d.dev, &d.func);
      hwNode *device = scan_pci_dev(d, n);

      if(device)
      {
        string resourcename = string(devices[i]->d_name)+"/resource";

        device->setBusInfo(devices[i]->d_name);
        if(exists(string(devices[i]->d_name)+"/driver"))
        {
          string drivername = readlink(string(devices[i]->d_name)+"/driver");
          string modulename = readlink(string(devices[i]->d_name)+"/driver/module");

          device->setConfig("driver", basename(drivername.c_str()));
          if(exists(modulename))
            device->setConfig("module", basename(modulename.c_str()));

          if(exists(string(devices[i]->d_name)+"/rom"))
          {
            device->addCapability("rom", "extension ROM");
          }

          if(exists(string(devices[i]->d_name)+"/irq"))
          {
            long irq = get_number(string(devices[i]->d_name)+"/irq", -1);
            if(irq>=0)
              device->addResource(hw::resource::irq(irq));
          }
          device->claim();
        }

        if(exists(resourcename))
        {
            FILE*resource = fopen(resourcename.c_str(), "r");

            if(resource)
            {
              while(!feof(resource))
              {
                unsigned long long start, end, flags;

                start = end = flags = 0;

                if(fscanf(resource, "%llx %llx %llx", &start, &end, &flags) != 3)
                  break;

                if(flags & 0x101)
                  device->addResource(hw::resource::ioport(start, end));
                else
                if(flags & 0x100)
                  device->addResource(hw::resource::iomem(start, end));
                else
                if(flags & 0x200)
                  device->addResource(hw::resource::mem(start, end, flags & 0x1000));
              }
              fclose(resource);
            }
        }

        result = true;
      }

      free(devices[i]);
    }

    free(devices);
  }
  popd();
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static hwNode* scan_pci_dev ( struct pci_dev d,
hwNode n 
) [static]

Definition at line 756 of file pci.cc.

{
  hwNode *result = NULL;
  hwNode *core = n.getChild("core");
  if (!core)
  {
    n.addChild(hwNode("core", hw::bus));
    core = n.getChild("core");
  }

  if(!pcidb_loaded)
    pcidb_loaded = load_pcidb();

      d.vendor_id = get_conf_word(d, PCI_VENDOR_ID);
      d.device_id = get_conf_word(d, PCI_DEVICE_ID);
      u_int16_t dclass = get_conf_word(d, PCI_CLASS_DEVICE);
      u_int16_t cmd = get_conf_word(d, PCI_COMMAND);
      u_int16_t status = get_conf_word(d, PCI_STATUS);
      u_int8_t latency = get_conf_byte(d, PCI_LATENCY_TIMER);
      u_int8_t min_gnt = get_conf_byte(d, PCI_MIN_GNT);
      u_int8_t max_lat = get_conf_byte(d, PCI_MAX_LAT);
      u_int8_t progif = get_conf_byte(d, PCI_CLASS_PROG);
      u_int8_t rev = get_conf_byte(d, PCI_REVISION_ID);
      u_int8_t htype = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f;
      u_int16_t subsys_v = 0, subsys_d = 0;

      char revision[10];
      snprintf(revision, sizeof(revision), "%02x", rev);
      string moredescription = get_class_description(dclass, progif);

      switch (htype)
      {
        case PCI_HEADER_TYPE_NORMAL:
          subsys_v = get_conf_word(d, PCI_SUBSYSTEM_VENDOR_ID);
          subsys_d = get_conf_word(d, PCI_SUBSYSTEM_ID);
          break;
        case PCI_HEADER_TYPE_BRIDGE:
          subsys_v = subsys_d = 0;
          latency = get_conf_byte(d, PCI_SEC_LATENCY_TIMER);
          break;
        case PCI_HEADER_TYPE_CARDBUS:
          subsys_v = get_conf_word(d, PCI_CB_SUBSYSTEM_VENDOR_ID);
          subsys_d = get_conf_word(d, PCI_CB_SUBSYSTEM_ID);
          latency = get_conf_byte(d, PCI_CB_LATENCY_TIMER);
          break;
      }

      if (dclass == PCI_CLASS_BRIDGE_HOST)
      {
        hwNode host("pci",
          hw::bridge);

        host.setDescription(get_class_description(dclass, progif));
        host.setVendor(get_device_description(d.vendor_id)+(enabled("output:numeric")?" ["+tohex(d.vendor_id)+"]":""));
        host.setProduct(get_device_description(d.vendor_id, d.device_id)+(enabled("output:numeric")?" ["+tohex(d.vendor_id)+":"+tohex(d.device_id)+"]":""));
        host.setHandle(pci_bushandle(d.bus, d.domain));
        host.setVersion(revision);
        addHints(host, d.vendor_id, d.device_id, subsys_v, subsys_d, dclass);
        host.claim();
        if(latency)
          host.setConfig("latency", latency);
        if (d.size[0] > 0)
          host.setPhysId(0x100 + d.domain);

        if (moredescription != "" && moredescription != host.getDescription())
        {
          host.addCapability(moredescription);
          host.setDescription(host.getDescription() + " (" +
            moredescription + ")");
        }

        if (status & PCI_STATUS_66MHZ)
          host.setClock(66000000UL);              // 66MHz
        else
          host.setClock(33000000UL);              // 33MHz

        scan_resources(host, d);

        if (core)
          result = core->addChild(host);
        else
          result = n.addChild(host);
      }
      else
      {
        hw::hwClass deviceclass = hw::generic;
        string devicename = "generic";
        string deviceicon = "";

        switch (dclass >> 8)
        {
          case PCI_BASE_CLASS_STORAGE:
            deviceclass = hw::storage;
            deviceicon = "disc";
            if(dclass == PCI_CLASS_STORAGE_SCSI)
              deviceicon = "scsi";
            if(dclass == PCI_CLASS_STORAGE_RAID)
              deviceicon = "raid";
            break;
          case PCI_BASE_CLASS_NETWORK:
            deviceclass = hw::network;
            deviceicon = "network";
            break;
          case PCI_BASE_CLASS_MEMORY:
            deviceclass = hw::memory;
            deviceicon = "memory";
            break;
          case PCI_BASE_CLASS_BRIDGE:
            deviceclass = hw::bridge;
            break;
          case PCI_BASE_CLASS_MULTIMEDIA:
            deviceclass = hw::multimedia;
            if(dclass == PCI_CLASS_MULTIMEDIA_AUDIO)
              deviceicon = "audio";
            break;
          case PCI_BASE_CLASS_DISPLAY:
            deviceclass = hw::display;
            deviceicon = "display";
            break;
          case PCI_BASE_CLASS_COMMUNICATION:
            deviceclass = hw::communication;
            if(dclass == PCI_CLASS_COMMUNICATION_SERIAL)
              deviceicon = "serial";
            if(dclass == PCI_CLASS_COMMUNICATION_PARALLEL)
              deviceicon = "parallel";
            if(dclass == PCI_CLASS_COMMUNICATION_MODEM)
              deviceicon = "modem";
            break;
          case PCI_BASE_CLASS_SYSTEM:
            deviceclass = hw::generic;
            break;
          case PCI_BASE_CLASS_INPUT:
            deviceclass = hw::input;
            break;
          case PCI_BASE_CLASS_PROCESSOR:
            deviceclass = hw::processor;
            break;
          case PCI_BASE_CLASS_SERIAL:
            deviceclass = hw::bus;
            if(dclass == PCI_CLASS_SERIAL_USB)
              deviceicon = "usb";
            if(dclass == PCI_CLASS_SERIAL_FIREWIRE)
              deviceicon = "firewire";
            break;
        }

        devicename = get_class_name(dclass);
        hwNode *device = new hwNode(devicename, deviceclass);

        if (device)
        {
          if(deviceicon != "") device->addHint("icon", deviceicon);
          addHints(*device, d.vendor_id, d.device_id, subsys_v, subsys_d, dclass);

          if (deviceclass == hw::bridge || deviceclass == hw::storage)
            device->addCapability(devicename);

          if(device->isCapable("isa") ||
            device->isCapable("pci") ||
            device->isCapable("agp"))
            device->claim();

          scan_resources(*device, d);
          scan_capabilities(*device, d);

          if (deviceclass == hw::display)
            for (int j = 0; j < 6; j++)
              if ((d.size[j] != 0xffffffff)
            && (d.size[j] > device->getSize()))
                device->setSize(d.size[j]);

          if (dclass == PCI_CLASS_BRIDGE_PCI)
          {
            device->setHandle(pci_bushandle(get_conf_byte(d, PCI_SECONDARY_BUS), d.domain));
            device->claim();
          }
          else
          {
            char irq[10];

            snprintf(irq, sizeof(irq), "%d", d.irq);
            device->setHandle(pci_handle(d.bus, d.dev, d.func, d.domain));
            device->setConfig("latency", latency);
            if(max_lat)
              device->setConfig("maxlatency", max_lat);
            if(min_gnt)
              device->setConfig("mingnt", min_gnt);
            if (d.irq != 0)
            {
//device->setConfig("irq", irq);
              device->addResource(hw::resource::irq(d.irq));
            }
          }
          device->setDescription(get_class_description(dclass));

          if (moredescription != ""
            && moredescription != device->getDescription())
          {
            device->addCapability(moredescription);
          }
          device->setVendor(get_device_description(d.vendor_id)+(enabled("output:numeric")?" ["+tohex(d.vendor_id)+"]":""));
          device->setVersion(revision);
          device->setProduct(get_device_description(d.vendor_id, d.device_id)+(enabled("output:numeric")?" ["+tohex(d.vendor_id)+":"+tohex(d.device_id)+"]":""));

          if (cmd & PCI_COMMAND_MASTER)
            device->addCapability("bus master", "bus mastering");
          if (cmd & PCI_COMMAND_VGA_PALETTE)
            device->addCapability("VGA palette", "VGA palette");
          if (status & PCI_STATUS_CAP_LIST)
            device->addCapability("cap list", "PCI capabilities listing");
          if (status & PCI_STATUS_66MHZ)
            device->setClock(66000000UL);         // 66MHz
          else
            device->setClock(33000000UL);         // 33MHz

          device->setPhysId(d.dev, d.func);

          hwNode *bus = NULL;

          bus = n.findChildByHandle(pci_bushandle(d.bus, d.domain));

          device->describeCapability("vga", "VGA graphical framebuffer");
          device->describeCapability("pcmcia", "PC-Card (PCMCIA)");
          device->describeCapability("generic", "Generic interface");
          device->describeCapability("ohci", "Open Host Controller Interface");
          device->describeCapability("uhci", "Universal Host Controller Interface (USB1)");
          device->describeCapability("ehci", "Enhanced Host Controller Interface (USB2)");
          if (bus)
            result = bus->addChild(*device);
          else
          {
            if (core)
              result = core->addChild(*device);
            else
              result = n.addChild(*device);
          }
          delete device;

        }
      }
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool scan_pci_legacy ( hwNode n)

Definition at line 999 of file pci.cc.

{
  FILE *f;
  hwNode *core = n.getChild("core");
  if (!core)
  {
    n.addChild(hwNode("core", hw::bus));
    core = n.getChild("core");
  }

  if(!pcidb_loaded)
    pcidb_loaded = load_pcidb();

  f = fopen(PROC_BUS_PCI "/devices", "r");
  if (f)
  {
    char buf[512];

    while (fgets(buf, sizeof(buf) - 1, f))
    {
      unsigned int dfn, vend, cnt;
      struct pci_dev d;
      int fd = -1;
      string devicepath = "";
      char devicename[20];
      char businfo[20];
      char driver[50];
      hwNode *device = NULL;

      memset(&d, 0, sizeof(d));
      memset(driver, 0, sizeof(driver));
      cnt = sscanf(buf,
        "%x %x %x %llx %llx %llx %llx %llx %llx %llx %llx %llx %llx %llx %llx %llx %llx %[ -z]s",
        &dfn,
        &vend,
        &d.irq,
        &d.base_addr[0],
        &d.base_addr[1],
        &d.base_addr[2],
        &d.base_addr[3],
        &d.base_addr[4],
        &d.base_addr[5],
        &d.rom_base_addr,
        &d.size[0],
        &d.size[1],
        &d.size[2],
        &d.size[3], &d.size[4], &d.size[5], &d.rom_size, driver);

      if (cnt != 9 && cnt != 10 && cnt != 17 && cnt != 18)
        break;

      d.bus = dfn >> 8;
      d.dev = PCI_SLOT(dfn & 0xff);
      d.func = PCI_FUNC(dfn & 0xff);
      d.vendor_id = vend >> 16;
      d.device_id = vend & 0xffff;

      snprintf(devicename, sizeof(devicename), "%02x/%02x.%x", d.bus, d.dev,
        d.func);
      devicepath = string(PROC_BUS_PCI) + "/" + string(devicename);
      snprintf(businfo, sizeof(businfo), "%02x:%02x.%x", d.bus, d.dev,
        d.func);

      fd = open(devicepath.c_str(), O_RDONLY);
      if (fd >= 0)
      {
        if(read(fd, d.config, sizeof(d.config)) != sizeof(d.config))
          memset(&d.config, 0, sizeof(d.config));
        close(fd);
      }

      device = scan_pci_dev(d, n);
      if(device)
      {
        device->setBusInfo(businfo);
      }

    }
    fclose(f);
  }

  return false;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool scan_resources ( hwNode n,
struct pci_dev d 
) [static]

Definition at line 615 of file pci.cc.

{
  u_int16_t cmd = get_conf_word(d, PCI_COMMAND);

  n.setWidth(32);

  for (int i = 0; i < 6; i++)
  {
    u_int32_t flg = get_conf_long(d, PCI_BASE_ADDRESS_0 + 4 * i);
    u_int32_t pos = d.base_addr[i];
    u_int32_t len = d.size[i];

    if (flg == 0xffffffff)
      flg = 0;

    if (!pos && !flg && !len)
      continue;

    if (pos && !flg)                              /* Reported by the OS, but not by the device */
    {
//printf("[virtual] ");
      flg = pos;
    }
    if (flg & PCI_BASE_ADDRESS_SPACE_IO)
    {
      u_int32_t a = pos & PCI_BASE_ADDRESS_IO_MASK;
      if ((a != 0) && (cmd & PCI_COMMAND_IO) != 0)
        n.addResource(hw::resource::ioport(a, a + len - 1));
    }
    else                                          // resource is memory
    {
      int t = flg & PCI_BASE_ADDRESS_MEM_TYPE_MASK;
      u_int64_t a = pos & PCI_ADDR_MEM_MASK;
      u_int64_t z = 0;

      if (t == PCI_BASE_ADDRESS_MEM_TYPE_64)
      {
        n.setWidth(64);
        if (i < 5)
        {
          i++;
          z = get_conf_long(d, PCI_BASE_ADDRESS_0 + 4 * i);
          a += z << 4;
        }
      }
      if (a)
        n.addResource(hw::resource::iomem(a, a + len - 1));
    }
  }

  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

vector< pci_entry > pci_classes [static]

Definition at line 249 of file pci.cc.

vector< pci_entry > pci_devices [static]

Definition at line 248 of file pci.cc.

bool pcidb_loaded = false

Definition at line 197 of file pci.cc.