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:
@@ -147,6 +147,14 @@ struct pci_module_info {
|
|||||||
);
|
);
|
||||||
|
|
||||||
void * (*ram_address) (const void *physical_address_in_system_memory);
|
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"
|
#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_debugport 0x0a
|
||||||
#define PCI_cap_id_cpci_rsrcctl 0x0b
|
#define PCI_cap_id_cpci_rsrcctl 0x0b
|
||||||
#define PCI_cap_id_hotplug 0x0c
|
#define PCI_cap_id_hotplug 0x0c
|
||||||
|
#define PCI_cap_id_sata 0x12 /* Serial ATA Capability */
|
||||||
|
|
||||||
/** Power Management Control Status Register settings */
|
/** Power Management Control Status Register settings */
|
||||||
#define PCI_pm_mask 0x03
|
#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
|
// #pragma mark bus manager init/uninit
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
|
|||||||
@@ -221,7 +221,8 @@ static struct pci_module_info sOldPCIModule = {
|
|||||||
&pci_get_nth_pci_info,
|
&pci_get_nth_pci_info,
|
||||||
&pci_read_config,
|
&pci_read_config,
|
||||||
&pci_write_config,
|
&pci_write_config,
|
||||||
&pci_ram_address
|
&pci_ram_address,
|
||||||
|
&pci_find_capability
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct pci_root_info sPCIModule = {
|
static struct pci_root_info sPCIModule = {
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ extern pci_device_module_info gPCIDeviceModule;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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);
|
status_t pci_io_init(void);
|
||||||
uint8 pci_read_io_8(int mapped_io_addr);
|
uint8 pci_read_io_8(int mapped_io_addr);
|
||||||
|
|||||||
Reference in New Issue
Block a user