Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1.  
  2. #define PCI_FIND_CAP_TTL    48
  3.  
  4. static int __pci_find_next_cap_ttl(PCITAG pciTag, u8_t pos,
  5.                                    int cap, int *ttl)
  6. {
  7.     u8_t id;
  8.  
  9.     while ((*ttl)--)
  10.     {
  11.         pos = pciReadByte(pciTag, pos);
  12.                 if (pos < 0x40)
  13.                         break;
  14.                 pos &= ~3;
  15.         id = pciReadByte(pciTag, pos + PCI_CAP_LIST_ID);
  16.                 if (id == 0xff)
  17.                         break;
  18.                 if (id == cap)
  19.                         return pos;
  20.                 pos += PCI_CAP_LIST_NEXT;
  21.         }
  22.         return 0;
  23. }
  24.  
  25. static int __pci_find_next_cap(PCITAG pciTag, u8_t pos, int cap)
  26. {
  27.         int ttl = PCI_FIND_CAP_TTL;
  28.  
  29.     return __pci_find_next_cap_ttl(pciTag, pos, cap, &ttl);
  30. }
  31.  
  32. static int __pci_bus_find_cap_start(PCITAG pciTag)
  33. {
  34.     u16_t status;
  35.     u8_t  hdr_type;
  36.  
  37.     status = pciReadWord(pciTag, PCI_STATUS);
  38.         if (!(status & PCI_STATUS_CAP_LIST))
  39.                 return 0;
  40.  
  41.     hdr_type = pciReadByte(pciTag, 0x0E);
  42.     switch (hdr_type)
  43.     {
  44.         case PCI_HEADER_TYPE_NORMAL:
  45.         case PCI_HEADER_TYPE_BRIDGE:
  46.             return PCI_CAPABILITY_LIST;
  47.         case PCI_HEADER_TYPE_CARDBUS:
  48.             return PCI_CB_CAPABILITY_LIST;
  49.         default:
  50.             return 0;
  51.         }
  52.         return 0;
  53. }
  54.  
  55.  
  56. int pci_find_capability(PCITAG pciTag, int cap)
  57. {
  58.         int pos;
  59.  
  60.     pos = __pci_bus_find_cap_start(pciTag);
  61.         if (pos)
  62.         pos = __pci_find_next_cap(pciTag, pos, cap);
  63.  
  64.         return pos;
  65. }
  66.  
  67.  
  68. PCITAG pci_find_class(u16_t class)
  69. {
  70.     u32_t bus, last_bus;
  71.     PCITAG tag;
  72.  
  73.     if( (last_bus = PciApi(1))==-1)
  74.         return -1;
  75.  
  76.     for(bus=0;bus<=last_bus;bus++)
  77.     {
  78.         u32_t devfn;
  79.  
  80.         for(devfn=0;devfn<256;devfn++)
  81.         {
  82.             u16_t devclass;
  83.  
  84.             devclass = PciRead16(bus,devfn, 0x0A);
  85.  
  86.             if( devclass != class)
  87.                 continue;
  88.  
  89.             return pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
  90.         };
  91.     };
  92.     return -1;
  93. };
  94.  
  95.  
  96. PCITAG pci_get_device(u32_t vendor, u32_t device, PCITAG from)
  97. {
  98.     u32_t bus, last_bus;
  99.     u32_t devfn;
  100.  
  101.     if( (last_bus = PciApi(1))==-1)
  102.         return -1;
  103.  
  104.     bus   = PCI_BUS_FROM_TAG(from);
  105.     devfn = PCI_DFN_FROM_TAG(from);
  106.  
  107.     devfn++;
  108.  
  109.     for(;bus<=last_bus; bus++)
  110.     {
  111.         for(;devfn < 256;devfn++)
  112.         {
  113.             u32_t tmp;
  114.             u32_t dev_vendor;
  115.             u32_t dev_id;
  116.  
  117.             tmp = PciRead32(bus,devfn, 0);
  118.  
  119.             dev_vendor = (u16_t)tmp;
  120.             dev_id = tmp >> 16;
  121.  
  122.             if ((vendor == PCI_ANY_ID || dev_vendor == vendor))
  123.                 return pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
  124.         };
  125.     };
  126.     return -1;
  127. }
  128.  
  129.