pci: added pci_find_extended_capability().
* added PCI Extended Capabilities definitions. * pci_find_capability() parameter offset is now optional.
This commit is contained in:
parent
e1c44764ef
commit
26a4510e59
@ -196,6 +196,7 @@ struct pci_module_info {
|
|||||||
#define PCI_header_type 0x0e /* (1 byte) header type */
|
#define PCI_header_type 0x0e /* (1 byte) header type */
|
||||||
#define PCI_bist 0x0f /* (1 byte) built-in self-test */
|
#define PCI_bist 0x0f /* (1 byte) built-in self-test */
|
||||||
|
|
||||||
|
#define PCI_extended_capability 0x100 /* (4 bytes) extended capability */
|
||||||
|
|
||||||
|
|
||||||
/* ---
|
/* ---
|
||||||
@ -690,6 +691,41 @@ struct pci_module_info {
|
|||||||
#define PCI_cap_id_sata 0x12 /* Serial ATA Capability */
|
#define PCI_cap_id_sata 0x12 /* Serial ATA Capability */
|
||||||
#define PCI_cap_id_pciaf 0x13 /* PCI Advanced Features */
|
#define PCI_cap_id_pciaf 0x13 /* PCI Advanced Features */
|
||||||
|
|
||||||
|
/** PCI Extended Capabilities */
|
||||||
|
#define PCI_extcap_id(x) (x & 0x0000ffff)
|
||||||
|
#define PCI_extcap_version(x) ((x & 0x000f0000) >> 16)
|
||||||
|
#define PCI_extcap_next_ptr(x) ((x & 0xfff00000) >> 20)
|
||||||
|
|
||||||
|
#define PCI_extcap_id_aer 0x0001 /* Advanced Error Reporting */
|
||||||
|
#define PCI_extcap_id_vc 0x0002 /* Virtual Channel */
|
||||||
|
#define PCI_extcap_id_serial 0x0003 /* Serial Number */
|
||||||
|
#define PCI_extcap_id_power_budget 0x0004 /* Power Budgeting */
|
||||||
|
#define PCI_extcap_id_rcl_decl 0x0005 /* Root Complex Link Declaration */
|
||||||
|
#define PCI_extcap_id_rcil_ctl 0x0006 /* Root Complex Internal Link Control */
|
||||||
|
#define PCI_extcap_id_rcec_assoc 0x0007 /* Root Complex Event Collector Association */
|
||||||
|
#define PCI_extcap_id_mfvc 0x0008 /* MultiFunction Virtual Channel */
|
||||||
|
#define PCI_extcap_id_vc2 0x0009 /* Virtual Channel 2 */
|
||||||
|
#define PCI_extcap_id_rcrb_header 0x000a /* RCRB Header */
|
||||||
|
#define PCI_extcap_id_vendor 0x000b /* Vendor Unique */
|
||||||
|
#define PCI_extcap_id_acs 0x000d /* Access Control Services */
|
||||||
|
#define PCI_extcap_id_ari 0x000e /* Alternative Routing Id Interpretation */
|
||||||
|
#define PCI_extcap_id_ats 0x000f /* Address Translation Services */
|
||||||
|
#define PCI_extcap_id_srio_virtual 0x0010 /* Single Root I/O Virtualization */
|
||||||
|
#define PCI_extcap_id_mrio_virtual 0x0011 /* Multiple Root I/O Virtual */
|
||||||
|
#define PCI_extcap_id_multicast 0x0012 /* Multicast */
|
||||||
|
#define PCI_extcap_id_page_request 0x0013 /* Page Request */
|
||||||
|
#define PCI_extcap_id_amd 0x0014 /* AMD Reserved */
|
||||||
|
#define PCI_extcap_id_resizable_bar 0x0015 /* Resizable Bar */
|
||||||
|
#define PCI_extcap_id_dyn_power_alloc 0x0016 /* Dynamic Power Allocation */
|
||||||
|
#define PCI_extcap_id_tph_requester 0x0017 /* TPH Requester */
|
||||||
|
#define PCI_extcap_id_latency_tolerance 0x0018 /* Latency Tolerance Reporting */
|
||||||
|
#define PCI_extcap_id_2ndpcie 0x0019 /* Secondary PCIe */
|
||||||
|
#define PCI_extcap_id_pmux 0x001a /* Protocol Multiplexing */
|
||||||
|
#define PCI_extcap_id_pasid 0x001b /* Process Address Space Id */
|
||||||
|
#define PCI_extcap_id_ln_requester 0x001c /* LN Requester */
|
||||||
|
#define PCI_extcap_id_dpc 0x001d /* Downstream Porto Containment */
|
||||||
|
#define PCI_extcap_id_l1pm 0x001e /* L1 Power Management Substates */
|
||||||
|
|
||||||
/** Power Management Control Status Register settings */
|
/** Power Management Control Status Register settings */
|
||||||
#define PCI_pm_mask 0x03
|
#define PCI_pm_mask 0x03
|
||||||
#define PCI_pm_ctrl 0x02
|
#define PCI_pm_ctrl 0x02
|
||||||
|
@ -75,8 +75,8 @@ pci_write_config(uint8 virtualBus, uint8 device, uint8 function, uint8 offset,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
pci_find_capability(uchar virtualBus, uchar device, uchar function,
|
pci_find_capability(uint8 virtualBus, uint8 device, uint8 function,
|
||||||
uchar capID, uchar *offset)
|
uint8 capID, uint8 *offset)
|
||||||
{
|
{
|
||||||
uint8 bus;
|
uint8 bus;
|
||||||
uint8 domain;
|
uint8 domain;
|
||||||
@ -87,6 +87,20 @@ pci_find_capability(uchar virtualBus, uchar device, uchar function,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
pci_find_extended_capability(uint8 virtualBus, uint8 device, uint8 function,
|
||||||
|
uint16 capID, uint16 *offset)
|
||||||
|
{
|
||||||
|
uint8 bus;
|
||||||
|
uint8 domain;
|
||||||
|
if (gPCI->ResolveVirtualBus(virtualBus, &domain, &bus) != B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
return gPCI->FindExtendedCapability(domain, bus, device, function, capID,
|
||||||
|
offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
pci_reserve_device(uchar virtualBus, uchar device, uchar function,
|
pci_reserve_device(uchar virtualBus, uchar device, uchar function,
|
||||||
const char *driverName, void *nodeCookie)
|
const char *driverName, void *nodeCookie)
|
||||||
@ -1548,14 +1562,10 @@ status_t
|
|||||||
PCI::FindCapability(uint8 domain, uint8 bus, uint8 device, uint8 function,
|
PCI::FindCapability(uint8 domain, uint8 bus, uint8 device, uint8 function,
|
||||||
uint8 capID, uint8 *offset)
|
uint8 capID, uint8 *offset)
|
||||||
{
|
{
|
||||||
if (offset == NULL) {
|
|
||||||
TRACE_CAP("PCI: FindCapability() ERROR %u:%u:%u capability %#02x offset NULL pointer\n", bus, device, function, capID);
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16 status = ReadConfig(domain, bus, device, function, PCI_status, 2);
|
uint16 status = ReadConfig(domain, bus, device, function, PCI_status, 2);
|
||||||
if (!(status & PCI_status_capabilities)) {
|
if (!(status & PCI_status_capabilities)) {
|
||||||
TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x not supported\n", bus, device, function, capID);
|
FLOW("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x "
|
||||||
|
"not supported\n", bus, device, function, capID);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1566,27 +1576,29 @@ PCI::FindCapability(uint8 domain, uint8 bus, uint8 device, uint8 function,
|
|||||||
switch (headerType & PCI_header_type_mask) {
|
switch (headerType & PCI_header_type_mask) {
|
||||||
case PCI_header_type_generic:
|
case PCI_header_type_generic:
|
||||||
case PCI_header_type_PCI_to_PCI_bridge:
|
case PCI_header_type_PCI_to_PCI_bridge:
|
||||||
capPointer = ReadConfig(domain, bus, device, function,
|
capPointer = PCI_capabilities_ptr;
|
||||||
PCI_capabilities_ptr, 1);
|
|
||||||
break;
|
break;
|
||||||
case PCI_header_type_cardbus:
|
case PCI_header_type_cardbus:
|
||||||
capPointer = ReadConfig(domain, bus, device, function,
|
capPointer = PCI_capabilities_ptr_2;
|
||||||
PCI_capabilities_ptr_2, 1);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x unknown header type\n", bus, device, function, capID);
|
TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability "
|
||||||
|
"%#02x unknown header type\n", bus, device, function, capID);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
capPointer = ReadConfig(domain, bus, device, function, capPointer, 1);
|
||||||
capPointer &= ~3;
|
capPointer &= ~3;
|
||||||
if (capPointer == 0) {
|
if (capPointer == 0) {
|
||||||
TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x empty list\n", bus, device, function, capID);
|
TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x "
|
||||||
|
"empty list\n", bus, device, function, capID);
|
||||||
return B_NAME_NOT_FOUND;
|
return B_NAME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 48; i++) {
|
for (int i = 0; i < 48; i++) {
|
||||||
if (ReadConfig(domain, bus, device, function, capPointer, 1) == capID) {
|
if (ReadConfig(domain, bus, device, function, capPointer, 1) == capID) {
|
||||||
*offset = capPointer;
|
if (offset != NULL)
|
||||||
|
*offset = capPointer;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1611,6 +1623,51 @@ PCI::FindCapability(PCIDev *device, uint8 capID, uint8 *offset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PCI::FindExtendedCapability(uint8 domain, uint8 bus, uint8 device,
|
||||||
|
uint8 function, uint16 capID, uint16 *offset)
|
||||||
|
{
|
||||||
|
if (FindCapability(domain, bus, device, function, PCI_cap_id_pcie)
|
||||||
|
!= B_OK) {
|
||||||
|
FLOW("PCI:FindExtendedCapability ERROR %u:%u:%u capability %#02x "
|
||||||
|
"not supported\n", bus, device, function, capID);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
uint16 capPointer = PCI_extended_capability;
|
||||||
|
uint32 capability = ReadConfig(domain, bus, device, function,
|
||||||
|
capPointer, 4);
|
||||||
|
|
||||||
|
if (capability == 0 || capability == 0xffffffff)
|
||||||
|
return B_NAME_NOT_FOUND;
|
||||||
|
|
||||||
|
for (int i = 0; i < 48; i++) {
|
||||||
|
if (PCI_extcap_id(capability) == capID) {
|
||||||
|
if (offset != NULL)
|
||||||
|
*offset = capPointer;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
capPointer = PCI_extcap_next_ptr(capability) & ~3;
|
||||||
|
if (capPointer < PCI_extended_capability)
|
||||||
|
return B_NAME_NOT_FOUND;
|
||||||
|
capability = ReadConfig(domain, bus, device, function,
|
||||||
|
capPointer, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE_CAP("PCI:FindExtendedCapability ERROR %u:%u:%u capability %#04x "
|
||||||
|
"circular list\n", bus, device, function, capID);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PCI::FindExtendedCapability(PCIDev *device, uint16 capID, uint16 *offset)
|
||||||
|
{
|
||||||
|
return FindExtendedCapability(device->domain, device->bus, device->device,
|
||||||
|
device->function, capID, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PCIDev *
|
PCIDev *
|
||||||
PCI::FindDevice(uint8 domain, uint8 bus, uint8 device, uint8 function)
|
PCI::FindDevice(uint8 domain, uint8 bus, uint8 device, uint8 function)
|
||||||
{
|
{
|
||||||
|
@ -92,9 +92,14 @@ public:
|
|||||||
|
|
||||||
status_t FindCapability(uint8 domain, uint8 bus,
|
status_t FindCapability(uint8 domain, uint8 bus,
|
||||||
uint8 device, uint8 function, uint8 capID,
|
uint8 device, uint8 function, uint8 capID,
|
||||||
uint8 *offset);
|
uint8 *offset = NULL);
|
||||||
status_t FindCapability(PCIDev *device, uint8 capID,
|
status_t FindCapability(PCIDev *device, uint8 capID,
|
||||||
uint8 *offset);
|
uint8 *offset = NULL);
|
||||||
|
status_t FindExtendedCapability(uint8 domain, uint8 bus,
|
||||||
|
uint8 device, uint8 function, uint16 capID,
|
||||||
|
uint16 *offset = NULL);
|
||||||
|
status_t FindExtendedCapability(PCIDev *device,
|
||||||
|
uint16 capID, uint16 *offset = NULL);
|
||||||
|
|
||||||
status_t ResolveVirtualBus(uint8 virtualBus, uint8 *domain,
|
status_t ResolveVirtualBus(uint8 virtualBus, uint8 *domain,
|
||||||
uint8 *bus);
|
uint8 *bus);
|
||||||
|
@ -46,7 +46,10 @@ extern "C" {
|
|||||||
|
|
||||||
void * pci_ram_address(const void *physical_address_in_system_memory);
|
void * pci_ram_address(const void *physical_address_in_system_memory);
|
||||||
|
|
||||||
status_t pci_find_capability(uchar bus, uchar device, uchar function, uchar cap_id, uchar *offset);
|
status_t pci_find_capability(uint8 bus, uint8 device, uint8 function,
|
||||||
|
uint8 cap_id, uint8 *offset = NULL);
|
||||||
|
status_t pci_find_extended_capability(uint8 bus, uint8 device, uint8 function,
|
||||||
|
uint16 cap_id, uint16 *offset = NULL);
|
||||||
|
|
||||||
status_t pci_reserve_device(uchar virtualBus, uchar device, uchar function,
|
status_t pci_reserve_device(uchar virtualBus, uchar device, uchar function,
|
||||||
const char *driverName, void *nodeCookie);
|
const char *driverName, void *nodeCookie);
|
||||||
|
Loading…
Reference in New Issue
Block a user