While Intel documentation lists PCI capability as 32 bit entities,
the PCI specifications lists it as two 8 bit entities, followed by a unknown number of vendor specific data. It should be better to do two 8 bit reads, instead of one 16 or 32 bit access. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@479 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
ef831f3638
commit
3fe5330ccb
@ -433,7 +433,7 @@ static int pci_get_capability(uint8 bus, uint8 dev, uint8 func, uint8 cap,
|
|||||||
uint8 *offs)
|
uint8 *offs)
|
||||||
{
|
{
|
||||||
uint16 status;
|
uint16 status;
|
||||||
uint32 reg_data;
|
uint8 cap_data;
|
||||||
uint8 hdr_type;
|
uint8 hdr_type;
|
||||||
uint8 ofs;
|
uint8 ofs;
|
||||||
int maxcount;
|
int maxcount;
|
||||||
@ -458,27 +458,33 @@ static int pci_get_capability(uint8 bus, uint8 dev, uint8 func, uint8 cap,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the 192 bytes vendor defined configuration space
|
/* the 192 bytes vendor defined configuration space can
|
||||||
* can hold as maximum 48 times a 32 bit capability
|
* hold as maximum 48 times a 32 bit aligned capability,
|
||||||
|
* we use this as abort condition to avoid lock up by
|
||||||
|
* searching in a circular loop on bad hardware
|
||||||
*/
|
*/
|
||||||
maxcount = 48;
|
maxcount = 48;
|
||||||
ofs = read_pci_config(bus, dev, func, ofs, 1);
|
ofs = read_pci_config(bus, dev, func, ofs, 1);
|
||||||
while (maxcount-- != 0 && ofs != 0) {
|
while (maxcount-- != 0 && ofs != 0) {
|
||||||
|
|
||||||
/* mask off potentially wrong bits */
|
/* mask off low two bits, demanded by PCI standard */
|
||||||
ofs &= ~3;
|
ofs &= ~3;
|
||||||
|
|
||||||
|
/* PCI specification 2.2, section 6.8.1.1 and following
|
||||||
|
* describe capability ID and next capability position as
|
||||||
|
* two 8 bit values, the "capability ID" is at the 32 bit
|
||||||
|
* aligned position, after it the "next pointer" follows.
|
||||||
|
*/
|
||||||
|
|
||||||
/* capabilities must be read as 32bit access */
|
/* read the 8 bit capability id is at the 32bit aligned ofs position */
|
||||||
reg_data = read_pci_config(bus, dev, func, ofs, 4);
|
cap_data = read_pci_config(bus, dev, func, ofs, 1);
|
||||||
|
if (cap_data == cap) {
|
||||||
/* lower 8 bit (0 to 7) contain the capability */
|
|
||||||
if ((reg_data & 0xff) == cap) {
|
|
||||||
if (offs)
|
if (offs)
|
||||||
*offs = ofs;
|
*offs = ofs;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* bit 8 to 15 contain next capability position */
|
/* at ofs + 1, we can read the next capability position */
|
||||||
ofs = (reg_data >> 8) & 0xff;
|
ofs = read_pci_config(bus, dev, func, ofs + 1, 1);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user