+#include <part/hard_reset.h>
+#include <part/fallback_boot.h>
+#include <delay.h>
+#if CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT == 1
+#include <device/hypertransport.h>
+#endif
+#if CONFIG_PCIX_PLUGIN_SUPPORT == 1
+#include <device/pcix.h>
+#endif
+#if CONFIG_PCIEXP_PLUGIN_SUPPORT == 1
+#include <device/pciexp.h>
+#endif
+#if CONFGI_AGP_PLUGIN_SUPPORT == 1
+#include <device/agp.h>
+#endif
+#if CONFIG_CARDBUS_PLUGIN_SUPPORT == 1
+#include <device/cardbus.h>
+#endif
+
+uint8_t pci_moving_config8(struct device *dev, unsigned reg)
+{
+ uint8_t value, ones, zeroes;
+ value = pci_read_config8(dev, reg);
+
+ pci_write_config8(dev, reg, 0xff);
+ ones = pci_read_config8(dev, reg);
+
+ pci_write_config8(dev, reg, 0x00);
+ zeroes = pci_read_config8(dev, reg);
+
+ pci_write_config8(dev, reg, value);
+
+ return ones ^ zeroes;
+}
+
+uint16_t pci_moving_config16(struct device *dev, unsigned reg)
+{
+ uint16_t value, ones, zeroes;
+ value = pci_read_config16(dev, reg);
+
+ pci_write_config16(dev, reg, 0xffff);
+ ones = pci_read_config16(dev, reg);
+
+ pci_write_config16(dev, reg, 0x0000);
+ zeroes = pci_read_config16(dev, reg);
+
+ pci_write_config16(dev, reg, value);
+
+ return ones ^ zeroes;
+}
+
+uint32_t pci_moving_config32(struct device *dev, unsigned reg)
+{
+ uint32_t value, ones, zeroes;
+ value = pci_read_config32(dev, reg);
+
+ pci_write_config32(dev, reg, 0xffffffff);
+ ones = pci_read_config32(dev, reg);
+
+ pci_write_config32(dev, reg, 0x00000000);
+ zeroes = pci_read_config32(dev, reg);
+
+ pci_write_config32(dev, reg, value);
+
+ return ones ^ zeroes;
+}
+
+unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last)
+{
+ unsigned pos;
+ unsigned status;
+ unsigned reps = 48;
+ pos = 0;
+ status = pci_read_config16(dev, PCI_STATUS);
+ if (!(status & PCI_STATUS_CAP_LIST)) {
+ return 0;
+ }
+ switch(dev->hdr_type & 0x7f) {
+ case PCI_HEADER_TYPE_NORMAL:
+ case PCI_HEADER_TYPE_BRIDGE:
+ pos = PCI_CAPABILITY_LIST;
+ break;
+ case PCI_HEADER_TYPE_CARDBUS:
+ pos = PCI_CB_CAPABILITY_LIST;
+ break;
+ default:
+ return 0;
+ }
+ pos = pci_read_config8(dev, pos);
+ while(reps-- && (pos >= 0x40)) { /* loop through the linked list */
+ int this_cap;
+ pos &= ~3;
+ this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
+ printk_spew("Capability: 0x%02x @ 0x%02x\n", cap, pos);
+ if (this_cap == 0xff) {
+ break;
+ }
+ if (!last && (this_cap == cap)) {
+ return pos;
+ }
+ if (last == pos) {
+ last = 0;
+ }
+ pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
+ }
+ return 0;
+}
+
+unsigned pci_find_capability(device_t dev, unsigned cap)
+{
+ return pci_find_next_capability(dev, cap, 0);
+
+}