static int match_pci_device(struct device *dev, int index, struct hardware_path *modpath) { struct pci_dev *pdev = to_pci_dev(dev); int id; if (index == 5) { /* we are at the end of the path, and on the actual device */ unsigned int devfn = pdev->devfn; return ((modpath->bc[5] == PCI_SLOT(devfn)) && (modpath->mod == PCI_FUNC(devfn))); } id = PCI_SLOT(pdev->devfn) | (PCI_FUNC(pdev->devfn) << 5); return (modpath->bc[index] == id); } static int match_parisc_device(struct device *dev, int index, struct hardware_path *modpath) { struct parisc_device *padev = to_parisc_device(dev); char id = (index == 6) ? modpath->mod : modpath->bc[index]; return (padev->id == id) } /** * parse_tree_node - returns a device entry in the iotree * @parent: the parent node in the tree * @id: the element of the module path for this entry */ struct device * parse_tree_node(struct device *parent, int index, struct hardware_path *modpath) { struct device *device; list_for_each_entry(device, parent->children, bus_list) { if (device->bus == &parisc_bus_type) { if (match_parisc_device(device, index, modpath)) return device; } else if (device->bus == &pci_bus_type) { if (match_pci_device(device, index, modpath)) return device; } else if (device->bus == 0) { struct device *new = parse_tree_node(device, index, modpath); if (new) return new; } } return NULL; } struct device *find_device(struct hardware_path *modpath) { int i; struct device *parent = &root.dev; for (i = 0; i < 6; i++) { if (modpath->bc[i] == -1) continue; parent = parse_tree_node(parent, i, modpath); if(!parent) return NULL; } if (parent->bus == &pci_bus_type) /* pci devices already parse mod XXX?*/ return parent; else return parse_tree_node(parent, 6, modpath); } EXPORT_SYMBOL(find_device);