/* Same as traverse_pci_devices except this does it for all phbs. */ void *traverse_all_pci_devices(traverse_func pre) { struct pci_controller* phb; void *ret; for (phb=hose_head;phb;phb=phb->next) if ((ret = traverse_pci_devices((struct device_node *)phb->arch_data, pre, NULL, phb)) != NULL) return ret; return NULL; }
/* * Same as traverse_pci_devices except this does it for all phbs. */ static void *traverse_all_pci_devices(traverse_func pre) { struct pci_controller *phb, *tmp; void *ret; list_for_each_entry_safe(phb, tmp, &hose_list, list_node) if ((ret = traverse_pci_devices(phb->arch_data, pre, phb)) != NULL) return ret; return NULL; }
/** * eeh_dev_phb_init_dynamic - Create EEH devices for devices included in PHB * @phb: PHB * * Scan the PHB OF node and its child association, then create the * EEH devices accordingly */ void eeh_dev_phb_init_dynamic(struct pci_controller *phb) { struct device_node *dn = phb->dn; /* EEH PE for PHB */ eeh_phb_pe_create(phb); /* EEH device for PHB */ eeh_dev_init(dn, phb); /* EEH devices for children OF nodes */ traverse_pci_devices(dn, eeh_dev_init, phb); }
/* This is the "slow" path for looking up a device_node from a * pci_dev. It will hunt for the device under its parent's * phb and then update sysdata for a future fastpath. * * It may also do fixups on the actual device since this happens * on the first read/write. * * Note that it also must deal with devices that don't exist. * In this case it may probe for real hardware ("just in case") * and add a device_node to the device tree if necessary. * */ struct device_node *fetch_dev_dn(struct pci_dev *dev) { struct device_node *orig_dn = (struct device_node *)dev->sysdata; struct pci_controller *phb = orig_dn->phb; /* assume same phb as orig_dn */ struct device_node *phb_dn; struct device_node *dn; unsigned long searchval = (dev->bus->number << 8) | dev->devfn; phb_dn = (struct device_node *)(phb->arch_data); dn = (struct device_node *)traverse_pci_devices(phb_dn, is_devfn_node, NULL, (void *)searchval); if (dn) { dev->sysdata = dn; /* ToDo: call some device init hook here */ } return dn; }
void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) { /* Update dn->phb ptrs for new phb and children devices */ traverse_pci_devices((struct device_node *)phb->arch_data, update_dn_pci_info, phb); }