]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/pci/pci.c
sf: Tidy up public and private header files
[karo-tx-uboot.git] / drivers / pci / pci.c
index 2c071589b4d075b1f3cba21ff85d783643219c49..28859f31612527ccff49ee3fbc69dbbc1caaaa54 100644 (file)
@@ -323,7 +323,7 @@ int __pci_hose_bus_to_phys(struct pci_controller *hose,
                        continue;
 
                if (bus_addr >= res->bus_start &&
-                       bus_addr < res->bus_start + res->size) {
+                       (bus_addr - res->bus_start) < res->size) {
                        *pa = (bus_addr - res->bus_start + res->phys_start);
                        return 0;
                }
@@ -648,6 +648,10 @@ int pci_hose_scan_bus(struct pci_controller *hose, int bus)
                pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device);
                pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
 
+#ifdef CONFIG_PCI_FIXUP_DEV
+               board_pci_fixup_dev(hose, dev, vendor, device, class);
+#endif
+
 #ifdef CONFIG_PCI_SCAN_SHOW
                indent++;
 
@@ -722,3 +726,68 @@ void pci_init(void)
        /* now call board specific pci_init()... */
        pci_init_board();
 }
+
+/* Returns the address of the requested capability structure within the
+ * device's PCI configuration space or 0 in case the device does not
+ * support it.
+ * */
+int pci_hose_find_capability(struct pci_controller *hose, pci_dev_t dev,
+                            int cap)
+{
+       int pos;
+       u8 hdr_type;
+
+       pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &hdr_type);
+
+       pos = pci_hose_find_cap_start(hose, dev, hdr_type & 0x7F);
+
+       if (pos)
+               pos = pci_find_cap(hose, dev, pos, cap);
+
+       return pos;
+}
+
+/* Find the header pointer to the Capabilities*/
+int pci_hose_find_cap_start(struct pci_controller *hose, pci_dev_t dev,
+                           u8 hdr_type)
+{
+       u16 status;
+
+       pci_hose_read_config_word(hose, dev, PCI_STATUS, &status);
+
+       if (!(status & PCI_STATUS_CAP_LIST))
+               return 0;
+
+       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;
+       }
+}
+
+int pci_find_cap(struct pci_controller *hose, pci_dev_t dev, int pos, int cap)
+{
+       int ttl = PCI_FIND_CAP_TTL;
+       u8 id;
+       u8 next_pos;
+
+       while (ttl--) {
+               pci_hose_read_config_byte(hose, dev, pos, &next_pos);
+               if (next_pos < CAP_START_POS)
+                       break;
+               next_pos &= ~3;
+               pos = (int) next_pos;
+               pci_hose_read_config_byte(hose, dev,
+                                         pos + PCI_CAP_LIST_ID, &id);
+               if (id == 0xff)
+                       break;
+               if (id == cap)
+                       return pos;
+               pos += PCI_CAP_LIST_NEXT;
+       }
+       return 0;
+}