+/**
+ * @brief Scan a PCI bus.
+ *
+ * Determine the existence of a given PCI device. Allocate a new struct device
+ * if dev==NULL was passed in and the device exists in hardware.
+ *
+ * @param bus pointer to the bus structure
+ * @param devfn to look at
+ *
+ * @return The device structure for hte device (if found)
+ * or the NULL if no device is found.
+ */
+device_t pci_probe_dev(device_t dev, struct bus * bus, unsigned devfn)
+{
+ u32 id, class;
+ u8 hdr_type;
+
+ /* Detect if a device is present. */
+ if (!dev) {
+ struct device dummy;
+ dummy.bus = bus;
+ dummy.path.type = DEVICE_PATH_PCI;
+ dummy.path.pci.devfn = devfn;
+ id = pci_read_config32(&dummy, PCI_VENDOR_ID);
+ /* Have we found something?
+ * Some broken boards return 0 if a slot is empty.
+ */
+ if ((id == 0xffffffff) || (id == 0x00000000) ||
+ (id == 0x0000ffff) || (id == 0xffff0000)) {
+ printk_spew("%s, bad id 0x%x\n", dev_path(&dummy), id);
+ return NULL;
+ }
+ dev = alloc_dev(bus, &dummy.path);
+ } else {
+ /* Enable/disable the device. Once we have found the device-
+ * specific operations this operations we will disable the
+ * device with those as well.
+ *
+ * This is geared toward devices that have subfunctions
+ * that do not show up by default.
+ *
+ * If a device is a stuff option on the motherboard
+ * it may be absent and enable_dev() must cope.
+ */
+ /* Run the magic enable sequence for the device. */
+ if (dev->chip_ops && dev->chip_ops->enable_dev) {
+ dev->chip_ops->enable_dev(dev);
+ }
+ /* Now read the vendor and device ID. */
+ id = pci_read_config32(dev, PCI_VENDOR_ID);
+
+ /* If the device does not have a PCI ID disable it. Possibly
+ * this is because we have already disabled the device. But
+ * this also handles optional devices that may not always
+ * show up.
+ */
+ /* If the chain is fully enumerated quit */
+ if ((id == 0xffffffff) || (id == 0x00000000) ||
+ (id == 0x0000ffff) || (id == 0xffff0000)) {
+ if (dev->enabled) {
+ printk_info("Disabling static device: %s\n",
+ dev_path(dev));
+ dev->enabled = 0;
+ }
+ return dev;
+ }
+ }
+ /* Read the rest of the PCI configuration information. */
+ hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
+ class = pci_read_config32(dev, PCI_CLASS_REVISION);
+
+ /* Store the interesting information in the device structure. */
+ dev->vendor = id & 0xffff;
+ dev->device = (id >> 16) & 0xffff;
+ dev->hdr_type = hdr_type;
+
+ /* Class code, the upper 3 bytes of PCI_CLASS_REVISION. */
+ dev->class = class >> 8;
+
+ /* Architectural/System devices always need to be bus masters. */
+ if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) {
+ dev->command |= PCI_COMMAND_MASTER;
+ }
+ /* Look at the vendor and device ID, or at least the header type and
+ * class and figure out which set of configuration methods to use.
+ * Unless we already have some PCI ops.
+ */
+ set_pci_ops(dev);
+
+ /* Now run the magic enable/disable sequence for the device. */
+ if (dev->ops && dev->ops->enable) {
+ dev->ops->enable(dev);
+ }
+
+ /* Display the device. */
+ printk_debug("%s [%04x/%04x] %s%s\n",
+ dev_path(dev),
+ dev->vendor, dev->device,
+ dev->enabled ? "enabled" : "disabled",
+ dev->ops ? "" : " No operations");
+
+ return dev;
+}
+
+/**
+ * @brief Scan a PCI bus.
+ *
+ * Determine the existence of devices and bridges on a PCI bus. If there are
+ * bridges on the bus, recursively scan the buses behind the bridges.
+ *
+ * This function is the default scan_bus() method for the root device
+ * 'dev_root'.
+ *