PCI: added FindHTCapability() for HyperTransport capabilities.
* untested. * as it's possible to have several HyperTransport capability blocks, the offset parameter is used as the start pointer for the search in case it's non zero.
This commit is contained in:
@@ -1668,6 +1668,60 @@ PCI::FindExtendedCapability(PCIDev *device, uint16 capID, uint16 *offset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PCI::FindHTCapability(uint8 domain, uint8 bus, uint8 device,
|
||||||
|
uint8 function, uint16 capID, uint8 *offset)
|
||||||
|
{
|
||||||
|
uint8 capPointer;
|
||||||
|
// consider the passed offset as the current ht capability block pointer
|
||||||
|
// when it's non zero
|
||||||
|
if (offset != NULL && *offset != 0) {
|
||||||
|
capPointer = ReadConfig(domain, bus, device, function, *offset + 1,
|
||||||
|
1);
|
||||||
|
} else if (FindCapability(domain, bus, device, function, PCI_cap_id_ht,
|
||||||
|
&capPointer) != B_OK) {
|
||||||
|
FLOW("PCI:FindHTCapability ERROR %u:%u:%u capability %#02x "
|
||||||
|
"not supported\n", bus, device, function, capID);
|
||||||
|
return B_NAME_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 mask = PCI_ht_command_cap_mask;
|
||||||
|
if (capID == PCI_ht_command_cap_slave || capID == PCI_ht_command_cap_host)
|
||||||
|
mask = 0xe000;
|
||||||
|
for (int i = 0; i < 48; i++) {
|
||||||
|
capPointer &= ~3;
|
||||||
|
if (capPointer == 0)
|
||||||
|
return B_NAME_NOT_FOUND;
|
||||||
|
|
||||||
|
uint8 capability = ReadConfig(domain, bus, device, function,
|
||||||
|
capPointer, 1);
|
||||||
|
if (capability == PCI_cap_id_ht) {
|
||||||
|
if ((ReadConfig(domain, bus, device, function,
|
||||||
|
capPointer + PCI_ht_command, 2) & mask) == capID) {
|
||||||
|
if (offset != NULL)
|
||||||
|
*offset = capPointer;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
capPointer = ReadConfig(domain, bus, device, function, capPointer + 1,
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE_CAP("PCI:FindHTCapability ERROR %u:%u:%u capability %#04x "
|
||||||
|
"circular list\n", bus, device, function, capID);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PCI::FindHTCapability(PCIDev *device, uint16 capID, uint8 *offset)
|
||||||
|
{
|
||||||
|
return FindHTCapability(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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -100,7 +100,12 @@ public:
|
|||||||
uint16 *offset = NULL);
|
uint16 *offset = NULL);
|
||||||
status_t FindExtendedCapability(PCIDev *device,
|
status_t FindExtendedCapability(PCIDev *device,
|
||||||
uint16 capID, uint16 *offset = NULL);
|
uint16 capID, uint16 *offset = NULL);
|
||||||
|
status_t FindHTCapability(uint8 domain, uint8 bus,
|
||||||
|
uint8 device, uint8 function, uint16 capID,
|
||||||
|
uint8 *offset);
|
||||||
|
status_t FindHTCapability(PCIDev *device,
|
||||||
|
uint16 capID, uint8 *offset = NULL);
|
||||||
|
|
||||||
status_t ResolveVirtualBus(uint8 virtualBus, uint8 *domain,
|
status_t ResolveVirtualBus(uint8 virtualBus, uint8 *domain,
|
||||||
uint8 *bus);
|
uint8 *bus);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user