probe.c
来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 815 行 · 第 1/2 页
C
815 行
pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses); if (!is_cardbus) { child->bridge_ctl = PCI_BRIDGE_CTL_NO_ISA; /* Now we can scan all subordinate buses... */ max = pci_scan_child_bus(child); } else { /* * For CardBus bridges, we leave 4 bus numbers * as cards with a PCI-to-PCI bridge can be * inserted later. */ max += CARDBUS_RESERVE_BUSNR; } /* * Set the subordinate bus number to its real value. */ child->subordinate = max; pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); } pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl); sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number); return max;}/* * Read interrupt line and base address registers. * The architecture-dependent code can tweak these, of course. */static void pci_read_irq(struct pci_dev *dev){ unsigned char irq; pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq); if (irq) pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); dev->irq = irq;}/** * pci_setup_device - fill in class and map information of a device * @dev: the device structure to fill * * Initialize the device structure with information about the device's * vendor,class,memory and IO-space addresses,IRQ lines etc. * Called at initialisation of the PCI subsystem and by CardBus services. * Returns 0 on success and -1 if unknown type of device (not normal, bridge * or CardBus). */static int pci_setup_device(struct pci_dev * dev){ u32 class; dev->slot_name = dev->dev.bus_id; sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus), dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); class >>= 8; /* upper 3 bytes */ dev->class = class; class >>= 8; DBG("Found %02x:%02x [%04x/%04x] %06x %02x\n", dev->bus->number, dev->devfn, dev->vendor, dev->device, class, dev->hdr_type); /* "Unknown power state" */ dev->current_state = 4; switch (dev->hdr_type) { /* header type */ case PCI_HEADER_TYPE_NORMAL: /* standard header */ if (class == PCI_CLASS_BRIDGE_PCI) goto bad; pci_read_irq(dev); pci_read_bases(dev, 6, PCI_ROM_ADDRESS); pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor); pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device); break; case PCI_HEADER_TYPE_BRIDGE: /* bridge header */ if (class != PCI_CLASS_BRIDGE_PCI) goto bad; /* The PCI-to-PCI bridge spec requires that subtractive decoding (i.e. transparent) bridge must have programming interface code of 0x01. */ dev->transparent = ((dev->class & 0xff) == 1); pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); break; case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */ if (class != PCI_CLASS_BRIDGE_CARDBUS) goto bad; pci_read_irq(dev); pci_read_bases(dev, 1, 0); pci_read_config_word(dev, PCI_CB_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor); pci_read_config_word(dev, PCI_CB_SUBSYSTEM_ID, &dev->subsystem_device); break; default: /* unknown header */ printk(KERN_ERR "PCI: device %s has unknown header type %02x, ignoring.\n", pci_name(dev), dev->hdr_type); return -1; bad: printk(KERN_ERR "PCI: %s: class %x doesn't match header type %02x. Ignoring class.\n", pci_name(dev), class, dev->hdr_type); dev->class = PCI_CLASS_NOT_DEFINED; } /* We found a fine healthy device, go go go... */ return 0;}/** * pci_release_dev - free a pci device structure when all users of it are finished. * @dev: device that's been disconnected * * Will be called only by the device core when all users of this pci device are * done. */static void pci_release_dev(struct device *dev){ struct pci_dev *pci_dev; pci_dev = to_pci_dev(dev); kfree(pci_dev);}/** * pci_cfg_space_size - get the configuration space size of the PCI device. * * Regular PCI devices have 256 bytes, but PCI-X 2 and PCI Express devices * have 4096 bytes. Even if the device is capable, that doesn't mean we can * access it. Maybe we don't have a way to generate extended config space * accesses, or the device is behind a reverse Express bridge. So we try * reading the dword at 0x100 which must either be 0 or a valid extended * capability header. */static int pci_cfg_space_size(struct pci_dev *dev){ int pos; u32 status; pos = pci_find_capability(dev, PCI_CAP_ID_EXP); if (!pos) { pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); if (!pos) goto fail; pci_read_config_dword(dev, pos + PCI_X_STATUS, &status); if (!(status & (PCI_X_STATUS_266MHZ | PCI_X_STATUS_533MHZ))) goto fail; } if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL) goto fail; if (status == 0xffffffff) goto fail; return PCI_CFG_SPACE_EXP_SIZE; fail: return PCI_CFG_SPACE_SIZE;}static void pci_release_bus_bridge_dev(struct device *dev){ kfree(dev);}/* * Read the config data for a PCI device, sanity-check it * and fill in the dev structure... */static struct pci_dev * __devinitpci_scan_device(struct pci_bus *bus, int devfn){ struct pci_dev *dev; u32 l; u8 hdr_type; if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type)) return NULL; if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l)) return NULL; /* some broken boards return 0 or ~0 if a slot is empty: */ if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000) return NULL; dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); if (!dev) return NULL; memset(dev, 0, sizeof(struct pci_dev)); dev->bus = bus; dev->sysdata = bus->sysdata; dev->dev.parent = bus->bridge; dev->dev.bus = &pci_bus_type; dev->devfn = devfn; dev->hdr_type = hdr_type & 0x7f; dev->multifunction = !!(hdr_type & 0x80); dev->vendor = l & 0xffff; dev->device = (l >> 16) & 0xffff; dev->cfg_size = pci_cfg_space_size(dev); /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer) set this higher, assuming the system even supports it. */ dev->dma_mask = 0xffffffff; if (pci_setup_device(dev) < 0) { kfree(dev); return NULL; } device_initialize(&dev->dev); dev->dev.release = pci_release_dev; pci_dev_get(dev); pci_name_device(dev); dev->dev.dma_mask = &dev->dma_mask; dev->dev.coherent_dma_mask = 0xffffffffull; return dev;}struct pci_dev * __devinitpci_scan_single_device(struct pci_bus *bus, int devfn){ struct pci_dev *dev; dev = pci_scan_device(bus, devfn); pci_scan_msi_device(dev); if (!dev) return NULL; /* Fix up broken headers */ pci_fixup_device(pci_fixup_header, dev); /* * Add the device to our list of discovered devices * and the bus list for fixup functions, etc. */ INIT_LIST_HEAD(&dev->global_list); list_add_tail(&dev->bus_list, &bus->devices); return dev;}/** * pci_scan_slot - scan a PCI slot on a bus for devices. * @bus: PCI bus to scan * @devfn: slot number to scan (must have zero function.) * * Scan a PCI slot on the specified PCI bus for devices, adding * discovered devices to the @bus->devices list. New devices * will have an empty dev->global_list head. */int __devinit pci_scan_slot(struct pci_bus *bus, int devfn){ int func, nr = 0; int scan_all_fns; scan_all_fns = pcibios_scan_all_fns(bus, devfn); for (func = 0; func < 8; func++, devfn++) { struct pci_dev *dev; dev = pci_scan_single_device(bus, devfn); if (dev) { nr++; /* * If this is a single function device, * don't scan past the first function. */ if (!dev->multifunction) { if (func > 0) { dev->multifunction = 1; } else { break; } } } else { if (func == 0 && !scan_all_fns) break; } } return nr;}unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus){ unsigned int devfn, pass, max = bus->secondary; struct pci_dev *dev; DBG("Scanning bus %02x\n", bus->number); /* Go find them, Rover! */ for (devfn = 0; devfn < 0x100; devfn += 8) pci_scan_slot(bus, devfn); /* * After performing arch-dependent fixup of the bus, look behind * all PCI-to-PCI bridges on this bus. */ DBG("Fixups for bus %02x\n", bus->number); pcibios_fixup_bus(bus); for (pass=0; pass < 2; pass++) list_for_each_entry(dev, &bus->devices, bus_list) { if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) max = pci_scan_bridge(bus, dev, max, pass); } /* * We've scanned the bus and so we know all about what's on * the other side of any bridges that may be on this bus plus * any devices. * * Return how far we've got finding sub-buses. */ DBG("Bus scan for %02x returning with max=%02x\n", bus->number, max); return max;}unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus){ unsigned int max; max = pci_scan_child_bus(bus); /* * Make the discovered devices available. */ pci_bus_add_devices(bus); return max;}struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata){ struct pci_bus *b; struct device *dev; b = pci_alloc_bus(); if (!b) return NULL; dev = kmalloc(sizeof(*dev), GFP_KERNEL); if (!dev){ kfree(b); return NULL; } b->sysdata = sysdata; b->ops = ops; if (pci_find_bus(pci_domain_nr(b), bus)) { /* If we already got to this bus through a different bridge, ignore it */ DBG("PCI: Bus %02x already known\n", bus); kfree(dev); kfree(b); return NULL; } list_add_tail(&b->node, &pci_root_buses); memset(dev, 0, sizeof(*dev)); dev->parent = parent; dev->release = pci_release_bus_bridge_dev; sprintf(dev->bus_id, "pci%04x:%02x", pci_domain_nr(b), bus); device_register(dev); b->bridge = get_device(dev); b->class_dev.class = &pcibus_class; sprintf(b->class_dev.class_id, "%04x:%02x", pci_domain_nr(b), bus); class_device_register(&b->class_dev); class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity); sysfs_create_link(&b->class_dev.kobj, &b->bridge->kobj, "bridge"); b->number = b->secondary = bus; b->resource[0] = &ioport_resource; b->resource[1] = &iomem_resource; b->subordinate = pci_scan_child_bus(b); pci_bus_add_devices(b); return b;}EXPORT_SYMBOL(pci_scan_bus_parented);#ifdef CONFIG_HOTPLUGEXPORT_SYMBOL(pci_add_new_bus);EXPORT_SYMBOL(pci_do_scan_bus);EXPORT_SYMBOL(pci_scan_slot);EXPORT_SYMBOL(pci_scan_bridge);EXPORT_SYMBOL(pci_scan_single_device);EXPORT_SYMBOL_GPL(pci_scan_child_bus);#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?