0,0 → 1,128 |
|
#define PCI_FIND_CAP_TTL 48 |
|
static int __pci_find_next_cap_ttl(PCITAG pciTag, u8_t pos, |
int cap, int *ttl) |
{ |
u8_t id; |
|
while ((*ttl)--) |
{ |
pos = pciReadByte(pciTag, pos); |
if (pos < 0x40) |
break; |
pos &= ~3; |
id = pciReadByte(pciTag, pos + PCI_CAP_LIST_ID); |
if (id == 0xff) |
break; |
if (id == cap) |
return pos; |
pos += PCI_CAP_LIST_NEXT; |
} |
return 0; |
} |
|
static int __pci_find_next_cap(PCITAG pciTag, u8_t pos, int cap) |
{ |
int ttl = PCI_FIND_CAP_TTL; |
|
return __pci_find_next_cap_ttl(pciTag, pos, cap, &ttl); |
} |
|
static int __pci_bus_find_cap_start(PCITAG pciTag) |
{ |
u16_t status; |
u8_t hdr_type; |
|
status = pciReadWord(pciTag, PCI_STATUS); |
if (!(status & PCI_STATUS_CAP_LIST)) |
return 0; |
|
hdr_type = pciReadByte(pciTag, 0x0E); |
switch (hdr_type) |
{ |
case PCI_HEADER_TYPE_NORMAL: |
case PCI_HEADER_TYPE_BRIDGE: |
return PCI_CAPABILITY_LIST; |
case PCI_HEADER_TYPE_CARDBUS: |
return PCI_CB_CAPABILITY_LIST; |
default: |
return 0; |
} |
return 0; |
} |
|
|
int pci_find_capability(PCITAG pciTag, int cap) |
{ |
int pos; |
|
pos = __pci_bus_find_cap_start(pciTag); |
if (pos) |
pos = __pci_find_next_cap(pciTag, pos, cap); |
|
return pos; |
} |
|
|
PCITAG pci_find_class(u16_t class) |
{ |
u32_t bus, last_bus; |
PCITAG tag; |
|
if( (last_bus = PciApi(1))==-1) |
return -1; |
|
for(bus=0;bus<=last_bus;bus++) |
{ |
u32_t devfn; |
|
for(devfn=0;devfn<256;devfn++) |
{ |
u16_t devclass; |
|
devclass = PciRead16(bus,devfn, 0x0A); |
|
if( devclass != class) |
continue; |
|
return pciTag(bus,(devfn>>3)&0x1F,devfn&0x7); |
}; |
}; |
return -1; |
}; |
|
|
PCITAG pci_get_device(u32_t vendor, u32_t device, PCITAG from) |
{ |
u32_t bus, last_bus; |
u32_t devfn; |
|
if( (last_bus = PciApi(1))==-1) |
return -1; |
|
bus = PCI_BUS_FROM_TAG(from); |
devfn = PCI_DFN_FROM_TAG(from); |
|
devfn++; |
|
for(;bus<=last_bus; bus++) |
{ |
for(;devfn < 256;devfn++) |
{ |
u32_t tmp; |
u32_t dev_vendor; |
u32_t dev_id; |
|
tmp = PciRead32(bus,devfn, 0); |
|
dev_vendor = (u16_t)tmp; |
dev_id = tmp >> 16; |
|
if ((vendor == PCI_ANY_ID || dev_vendor == vendor)) |
return pciTag(bus,(devfn>>3)&0x1F,devfn&0x7); |
}; |
}; |
return -1; |
} |
|