/* We check the return of @cb each time. If it returns anything other than 0, we break out.  */
void pci_walk_bus(struct pci_bus *top, int(*cb)(struct pci_dev *, void *), void *userdata)
/* We check the return of @cb each time. If it returns anything other than 0, we break out.  */
void pci_walk_bus(struct pci_bus *top, int(*cb)(struct pci_dev *, void *), void *userdata)
{
	struct pci_dev *dev;
	struct pci_bus *bus;
	struct list_head *next;
	int retval;
	bus = top;
	down_read(&pci_bus_sem);
	next = top->devices.next;
	for (;;) {
		if (next == &bus->devices) {
			if (bus == top)
				break;
			next = bus->self->bus_list.next;
			bus = bus->self->bus;
			continue;
		}
		dev = list_entry(next, struct pci_dev, bus_list);
		if (dev->subordinate) {
			next = dev->subordinate->devices.next;
			bus = dev->subordinate;
		} else
			next = dev->bus_list.next;
		down(&dev->dev.sem);
		retval = cb(dev, userdata);
		up(&dev->dev.sem);
		if (retval)
			break;
	}
	up_read(&pci_bus_sem);
}