Added support function to find a PCI capability offset in the configuration data, needed for SATA support.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20149 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
3f493ef624
commit
13dbe1c7ff
@ -147,6 +147,14 @@ struct pci_module_info {
|
||||
);
|
||||
|
||||
void * (*ram_address) (const void *physical_address_in_system_memory);
|
||||
|
||||
status_t (*find_pci_capability) (
|
||||
uchar bus,
|
||||
uchar device,
|
||||
uchar function,
|
||||
uchar cap_id,
|
||||
uchar *offset
|
||||
);
|
||||
};
|
||||
|
||||
#define B_PCI_MODULE_NAME "bus_managers/pci/v1"
|
||||
@ -617,6 +625,7 @@ struct pci_module_info {
|
||||
#define PCI_cap_id_debugport 0x0a
|
||||
#define PCI_cap_id_cpci_rsrcctl 0x0b
|
||||
#define PCI_cap_id_hotplug 0x0c
|
||||
#define PCI_cap_id_sata 0x12 /* Serial ATA Capability */
|
||||
|
||||
/** Power Management Control Status Register settings */
|
||||
#define PCI_pm_mask 0x03
|
||||
|
@ -64,6 +64,64 @@ pci_write_config(uint8 virt_bus, uint8 device, uint8 function, uint8 offset, uin
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
pci_find_capability(uchar bus, uchar device, uchar function, uchar cap_id, uchar *offset)
|
||||
{
|
||||
uint16 status;
|
||||
uint8 header_type;
|
||||
uint8 cap_ptr;
|
||||
int i;
|
||||
|
||||
if (!offset) {
|
||||
dprintf("find_pci_capability: ERROR %02x:%02x:%02x cap %02x offset NULL pointer\n", bus, device, function, cap_id);
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
status = pci_read_config(bus, device, function, PCI_status, 2);
|
||||
if (!(status & PCI_status_capabilities)) {
|
||||
dprintf("find_pci_capability: ERROR %02x:%02x:%02x cap %02x not supported\n", bus, device, function, cap_id);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
header_type = pci_read_config(bus, device, function, PCI_header_type, 1);
|
||||
switch (header_type & PCI_header_type_mask) {
|
||||
case PCI_header_type_generic:
|
||||
case PCI_header_type_PCI_to_PCI_bridge:
|
||||
cap_ptr = pci_read_config(bus, device, function, PCI_capabilities_ptr, 1);
|
||||
break;
|
||||
case PCI_header_type_cardbus:
|
||||
cap_ptr = pci_read_config(bus, device, function, PCI_capabilities_ptr_2, 1);
|
||||
break;
|
||||
default:
|
||||
dprintf("find_pci_capability: ERROR %02x:%02x:%02x cap %02x unknown header type\n", bus, device, function, cap_id);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
cap_ptr &= ~3;
|
||||
if (!cap_ptr) {
|
||||
dprintf("find_pci_capability: ERROR %02x:%02x:%02x cap %02x empty list\n", bus, device, function, cap_id);
|
||||
return B_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
for (i = 0; i < 48; i++) {
|
||||
uint8 this_cap_id = pci_read_config(bus, device, function, cap_ptr, 1);
|
||||
if (this_cap_id == cap_id) {
|
||||
*offset = cap_ptr;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
cap_ptr = pci_read_config(bus, device, function, cap_ptr + 1, 1);
|
||||
cap_ptr &= ~3;
|
||||
|
||||
if (!cap_ptr)
|
||||
return B_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
dprintf("find_pci_capability: ERROR %02x:%02x:%02x cap %02x circular list\n", bus, device, function, cap_id);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark bus manager init/uninit
|
||||
|
||||
status_t
|
||||
|
@ -221,7 +221,8 @@ static struct pci_module_info sOldPCIModule = {
|
||||
&pci_get_nth_pci_info,
|
||||
&pci_read_config,
|
||||
&pci_write_config,
|
||||
&pci_ram_address
|
||||
&pci_ram_address,
|
||||
&pci_find_capability
|
||||
};
|
||||
|
||||
static struct pci_root_info sPCIModule = {
|
||||
|
@ -41,7 +41,9 @@ extern pci_device_module_info gPCIDeviceModule;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
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_io_init(void);
|
||||
uint8 pci_read_io_8(int mapped_io_addr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user