⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
                               int offset, int len, u32 *val){        struct pci_controller *hose;        volatile void __iomem *addr;        hose = pci_bus_to_host(bus);        if (hose == NULL)                return PCIBIOS_DEVICE_NOT_FOUND;        if (offset >= 0x1000)                return  PCIBIOS_BAD_REGISTER_NUMBER;        addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset);        if (!addr)                return PCIBIOS_DEVICE_NOT_FOUND;        /*         * Note: the caller has already checked that offset is         * suitably aligned and that len is 1, 2 or 4.         */        switch (len) {        case 1:                *val = in_8(addr);                break;        case 2:                *val = in_le16(addr);                break;        default:                *val = in_le32(addr);                break;        }        return PCIBIOS_SUCCESSFUL;}static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn,                                int offset, int len, u32 val){        struct pci_controller *hose;        volatile void __iomem *addr;        hose = pci_bus_to_host(bus);        if (hose == NULL)                return PCIBIOS_DEVICE_NOT_FOUND;        if (offset >= 0x1000)                return  PCIBIOS_BAD_REGISTER_NUMBER;        addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset);        if (!addr)                return PCIBIOS_DEVICE_NOT_FOUND;        /*         * Note: the caller has already checked that offset is         * suitably aligned and that len is 1, 2 or 4.         */        switch (len) {        case 1:                out_8(addr, val);                break;        case 2:                out_le16(addr, val);                break;        default:                out_le32(addr, val);                break;        }        return PCIBIOS_SUCCESSFUL;}static struct pci_ops u4_pcie_pci_ops ={	.read = u4_pcie_read_config,	.write = u4_pcie_write_config,};static void __init setup_u3_agp(struct pci_controller* hose){	/* On G5, we move AGP up to high bus number so we don't need	 * to reassign bus numbers for HT. If we ever have P2P bridges	 * on AGP, we'll have to move pci_assign_all_buses to the	 * pci_controller structure so we enable it for AGP and not for	 * HT childs.	 * We hard code the address because of the different size of	 * the reg address cell, we shall fix that by killing struct	 * reg_property and using some accessor functions instead	 */	hose->first_busno = 0xf0;	hose->last_busno = 0xff;	hose->ops = &u3_agp_pci_ops;	hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);	hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);	u3_agp = hose;}static void __init setup_u4_pcie(struct pci_controller* hose){        /* We currently only implement the "non-atomic" config space, to         * be optimised later.         */        hose->ops = &u4_pcie_pci_ops;        hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);        hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);        u4_pcie = hose;}static void __init setup_u3_ht(struct pci_controller* hose){	hose->ops = &u3_ht_pci_ops;	/* We hard code the address because of the different size of	 * the reg address cell, we shall fix that by killing struct	 * reg_property and using some accessor functions instead	 */	hose->cfg_data = ioremap(0xf2000000, 0x02000000);	hose->first_busno = 0;	hose->last_busno = 0xef;	u3_ht = hose;}static int __init maple_add_bridge(struct device_node *dev){	int len;	struct pci_controller *hose;	char* disp_name;	const int *bus_range;	int primary = 1;	DBG("Adding PCI host bridge %s\n", dev->full_name);	bus_range = of_get_property(dev, "bus-range", &len);	if (bus_range == NULL || len < 2 * sizeof(int)) {		printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",		dev->full_name);	}	hose = pcibios_alloc_controller(dev);	if (hose == NULL)		return -ENOMEM;	hose->first_busno = bus_range ? bus_range[0] : 0;	hose->last_busno = bus_range ? bus_range[1] : 0xff;	disp_name = NULL;	if (of_device_is_compatible(dev, "u3-agp")) {		setup_u3_agp(hose);		disp_name = "U3-AGP";		primary = 0;	} else if (of_device_is_compatible(dev, "u3-ht")) {		setup_u3_ht(hose);		disp_name = "U3-HT";		primary = 1;        } else if (of_device_is_compatible(dev, "u4-pcie")) {                setup_u4_pcie(hose);                disp_name = "U4-PCIE";                primary = 0;	}	printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n",		disp_name, hose->first_busno, hose->last_busno);	/* Interpret the "ranges" property */	/* This also maps the I/O region and sets isa_io/mem_base */	pci_process_bridge_OF_ranges(hose, dev, primary);	/* Fixup "bus-range" OF property */	fixup_bus_range(dev);	/* Check for legacy IOs */	isa_bridge_find_early(hose);	return 0;}void __devinit maple_pci_irq_fixup(struct pci_dev *dev){	DBG(" -> maple_pci_irq_fixup\n");	/* Fixup IRQ for PCIe host */	if (u4_pcie != NULL && dev->bus->number == 0 &&	    pci_bus_to_host(dev->bus) == u4_pcie) {		printk(KERN_DEBUG "Fixup U4 PCIe IRQ\n");		dev->irq = irq_create_mapping(NULL, 1);		if (dev->irq != NO_IRQ)			set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);	}	/* Hide AMD8111 IDE interrupt when in legacy mode so	 * the driver calls pci_get_legacy_ide_irq()	 */	if (dev->vendor == PCI_VENDOR_ID_AMD &&	    dev->device == PCI_DEVICE_ID_AMD_8111_IDE &&	    (dev->class & 5) != 5) {		dev->irq = NO_IRQ;	}	DBG(" <- maple_pci_irq_fixup\n");}void __init maple_pci_init(void){	struct device_node *np, *root;	struct device_node *ht = NULL;	/* Probe root PCI hosts, that is on U3 the AGP host and the	 * HyperTransport host. That one is actually "kept" around	 * and actually added last as it's resource management relies	 * on the AGP resources to have been setup first	 */	root = of_find_node_by_path("/");	if (root == NULL) {		printk(KERN_CRIT "maple_find_bridges: can't find root of device tree\n");		return;	}	for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {		if (!np->type)			continue;		if (strcmp(np->type, "pci") && strcmp(np->type, "ht"))			continue;		if ((of_device_is_compatible(np, "u4-pcie") ||		     of_device_is_compatible(np, "u3-agp")) &&		    maple_add_bridge(np) == 0)			of_node_get(np);		if (of_device_is_compatible(np, "u3-ht")) {			of_node_get(np);			ht = np;		}	}	of_node_put(root);	/* Now setup the HyperTransport host if we found any	 */	if (ht && maple_add_bridge(ht) != 0)		of_node_put(ht);	/* Setup the linkage between OF nodes and PHBs */ 	pci_devs_phb_init();	/* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We	 * assume there is no P2P bridge on the AGP bus, which should be a	 * safe assumptions hopefully.	 */	if (u3_agp) {		struct device_node *np = u3_agp->arch_data;		PCI_DN(np)->busno = 0xf0;		for (np = np->child; np; np = np->sibling)			PCI_DN(np)->busno = 0xf0;	}	/* Tell pci.c to not change any resource allocations.  */	pci_probe_only = 1;}int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel){	struct device_node *np;	unsigned int defirq = channel ? 15 : 14;	unsigned int irq;	if (pdev->vendor != PCI_VENDOR_ID_AMD ||	    pdev->device != PCI_DEVICE_ID_AMD_8111_IDE)		return defirq;	np = pci_device_to_OF_node(pdev);	if (np == NULL) {		printk("Failed to locate OF node for IDE %s\n",		       pci_name(pdev));		return defirq;	}	irq = irq_of_parse_and_map(np, channel & 0x1);	if (irq == NO_IRQ) {		printk("Failed to map onboard IDE interrupt for channel %d\n",		       channel);		return defirq;	}	return irq;}/* XXX: To remove once all firmwares are ok */static void fixup_maple_ide(struct pci_dev* dev){	if (!machine_is(maple))		return;#if 0 /* Enable this to enable IDE port 0 */	{		u8 v;		pci_read_config_byte(dev, 0x40, &v);		v |= 2;		pci_write_config_byte(dev, 0x40, v);	}#endif#if 0 /* fix bus master base */	pci_write_config_dword(dev, 0x20, 0xcc01);	printk("old ide resource: %lx -> %lx \n",	       dev->resource[4].start, dev->resource[4].end);	dev->resource[4].start = 0xcc00;	dev->resource[4].end = 0xcc10;#endif#if 0 /* Enable this to fixup IDE sense/polarity of irqs in IO-APICs */	{		struct pci_dev *apicdev;		u32 v;		apicdev = pci_get_slot (dev->bus, PCI_DEVFN(5,0));		if (apicdev == NULL)			printk("IDE Fixup IRQ: Can't find IO-APIC !\n");		else {			pci_write_config_byte(apicdev, 0xf2, 0x10 + 2*14);			pci_read_config_dword(apicdev, 0xf4, &v);			v &= ~0x00000022;			pci_write_config_dword(apicdev, 0xf4, v);			pci_write_config_byte(apicdev, 0xf2, 0x10 + 2*15);			pci_read_config_dword(apicdev, 0xf4, &v);			v &= ~0x00000022;			pci_write_config_dword(apicdev, 0xf4, v);			pci_dev_put(apicdev);		}	}#endif}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE,			 fixup_maple_ide);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -