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

📄 pci_schizo.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
		prom_printf("%s: Cannot register CE interrupt.\n",			    pbm->name);		prom_halt();	}	bucket = __bucket(irq);	tmp = upa_readl(bucket->imap);	upa_writel(tmp, (pbm->pbm_regs +			 schizo_imap_offset(SCHIZO_CE_INO) + 4));	pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO);	irq = schizo_irq_build(pbm, NULL, ((pbm->portid << 6) |					   SCHIZO_PCIERR_A_INO));	if (request_irq(irq, schizo_pcierr_intr,			SA_SHIRQ, "TOMATILLO PCIERR", pbm) < 0) {		prom_printf("%s: Cannot register PBM A PciERR interrupt.\n",			    pbm->name);		prom_halt();	}	bucket = __bucket(irq);	tmp = upa_readl(bucket->imap);	upa_writel(tmp, (pbm->pbm_regs +			 schizo_imap_offset(SCHIZO_PCIERR_A_INO) + 4));	pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO);	irq = schizo_irq_build(pbm, NULL, ((pbm->portid << 6) |					    SCHIZO_PCIERR_B_INO));	if (request_irq(irq, schizo_pcierr_intr,			SA_SHIRQ, "TOMATILLO PCIERR", pbm) < 0) {		prom_printf("%s: Cannot register PBM B PciERR interrupt.\n",			    pbm->name);		prom_halt();	}	bucket = __bucket(irq);	tmp = upa_readl(bucket->imap);	upa_writel(tmp, (pbm->pbm_regs +			 schizo_imap_offset(SCHIZO_PCIERR_B_INO) + 4));	pbm = pbm_for_ino(p, SCHIZO_SERR_INO);	irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_SERR_INO);	if (request_irq(irq, schizo_safarierr_intr,			SA_SHIRQ, "TOMATILLO SERR", p) < 0) {		prom_printf("%s: Cannot register SafariERR interrupt.\n",			    pbm->name);		prom_halt();	}	bucket = __bucket(irq);	tmp = upa_readl(bucket->imap);	upa_writel(tmp, (pbm->pbm_regs +			 schizo_imap_offset(SCHIZO_SERR_INO) + 4));	/* Enable UE and CE interrupts for controller. */	schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL,		     (SCHIZO_ECCCTRL_EE |		      SCHIZO_ECCCTRL_UE |		      SCHIZO_ECCCTRL_CE));	schizo_write(p->pbm_B.controller_regs + SCHIZO_ECC_CTRL,		     (SCHIZO_ECCCTRL_EE |		      SCHIZO_ECCCTRL_UE |		      SCHIZO_ECCCTRL_CE));	/* Enable PCI Error interrupts and clear error	 * bits.	 */	err_mask = (SCHIZO_PCICTRL_BUS_UNUS |		    SCHIZO_PCICTRL_TTO_ERR |		    SCHIZO_PCICTRL_RTRY_ERR |		    SCHIZO_PCICTRL_SERR |		    SCHIZO_PCICTRL_EEN);	err_no_mask = SCHIZO_PCICTRL_DTO_ERR;	tmp = schizo_read(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL);	tmp |= err_mask;	tmp &= ~err_no_mask;	schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL, tmp);	tmp = schizo_read(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL);	tmp |= err_mask;	tmp &= ~err_no_mask;	schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL, tmp);	err_mask = (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA |		    SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR |		    SCHIZO_PCIAFSR_PTTO |		    SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA |		    SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR |		    SCHIZO_PCIAFSR_STTO);	schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_AFSR, err_mask);	schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_AFSR, err_mask);	err_mask = (BUS_ERROR_BADCMD | BUS_ERROR_SNOOP_GR |		    BUS_ERROR_SNOOP_PCI | BUS_ERROR_SNOOP_RD |		    BUS_ERROR_SNOOP_RDS | BUS_ERROR_SNOOP_RDSA |		    BUS_ERROR_SNOOP_OWN | BUS_ERROR_SNOOP_RDO |		    BUS_ERROR_WDATA_PERR | BUS_ERROR_CTRL_PERR |		    BUS_ERROR_SNOOP_ERR | BUS_ERROR_JBUS_ILL_B |		    BUS_ERROR_JBUS_ILL_C | BUS_ERROR_RD_PERR |		    BUS_ERROR_APERR | BUS_ERROR_UNMAP |		    BUS_ERROR_BUSERR | BUS_ERROR_TIMEOUT);	schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_ERRCTRL,		     (SCHIZO_SAFERRCTRL_EN | err_mask));	schizo_write(p->pbm_B.controller_regs + SCHIZO_SAFARI_ERRCTRL,		     (SCHIZO_SAFERRCTRL_EN | err_mask));	schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_IRQCTRL,		     (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP)));	schizo_write(p->pbm_B.controller_regs + SCHIZO_SAFARI_IRQCTRL,		     (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP)));}static void schizo_register_error_handlers(struct pci_controller_info *p){	struct pci_pbm_info *pbm;	unsigned int irq;	struct ino_bucket *bucket;	u64 tmp, err_mask, err_no_mask;	/* Build IRQs and register handlers. */	pbm = pbm_for_ino(p, SCHIZO_UE_INO);	irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_UE_INO);	if (request_irq(irq, schizo_ue_intr,			SA_SHIRQ, "SCHIZO UE", p) < 0) {		prom_printf("%s: Cannot register UE interrupt.\n",			    pbm->name);		prom_halt();	}	bucket = __bucket(irq);	tmp = upa_readl(bucket->imap);	upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_UE_INO) + 4));	pbm = pbm_for_ino(p, SCHIZO_CE_INO);	irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_CE_INO);	if (request_irq(irq, schizo_ce_intr,			SA_SHIRQ, "SCHIZO CE", p) < 0) {		prom_printf("%s: Cannot register CE interrupt.\n",			    pbm->name);		prom_halt();	}	bucket = __bucket(irq);	tmp = upa_readl(bucket->imap);	upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_CE_INO) + 4));	pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO);	irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_PCIERR_A_INO);	if (request_irq(irq, schizo_pcierr_intr,			SA_SHIRQ, "SCHIZO PCIERR", pbm) < 0) {		prom_printf("%s: Cannot register PBM A PciERR interrupt.\n",			    pbm->name);		prom_halt();	}	bucket = __bucket(irq);	tmp = upa_readl(bucket->imap);	upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_PCIERR_A_INO) + 4));	pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO);	irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_PCIERR_B_INO);	if (request_irq(irq, schizo_pcierr_intr,			SA_SHIRQ, "SCHIZO PCIERR", &p->pbm_B) < 0) {		prom_printf("%s: Cannot register PBM B PciERR interrupt.\n",			    pbm->name);		prom_halt();	}	bucket = __bucket(irq);	tmp = upa_readl(bucket->imap);	upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_PCIERR_B_INO) + 4));	pbm = pbm_for_ino(p, SCHIZO_SERR_INO);	irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_SERR_INO);	if (request_irq(irq, schizo_safarierr_intr,			SA_SHIRQ, "SCHIZO SERR", p) < 0) {		prom_printf("%s: Cannot register SafariERR interrupt.\n",			    pbm->name);		prom_halt();	}	bucket = __bucket(irq);	tmp = upa_readl(bucket->imap);	upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_SERR_INO) + 4));	/* Enable UE and CE interrupts for controller. */	schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL,		     (SCHIZO_ECCCTRL_EE |		      SCHIZO_ECCCTRL_UE |		      SCHIZO_ECCCTRL_CE));	err_mask = (SCHIZO_PCICTRL_BUS_UNUS |		    SCHIZO_PCICTRL_ESLCK |		    SCHIZO_PCICTRL_TTO_ERR |		    SCHIZO_PCICTRL_RTRY_ERR |		    SCHIZO_PCICTRL_SBH_ERR |		    SCHIZO_PCICTRL_SERR |		    SCHIZO_PCICTRL_EEN);	err_no_mask = (SCHIZO_PCICTRL_DTO_ERR |		       SCHIZO_PCICTRL_SBH_INT);	/* Enable PCI Error interrupts and clear error	 * bits for each PBM.	 */	tmp = schizo_read(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL);	tmp |= err_mask;	tmp &= ~err_no_mask;	schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL, tmp);	schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_AFSR,		     (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA |		      SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR |		      SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS |		      SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA |		      SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR |		      SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS));	tmp = schizo_read(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL);	tmp |= err_mask;	tmp &= ~err_no_mask;	schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL, tmp);	schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_AFSR,		     (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA |		      SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR |		      SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS |		      SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA |		      SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR |		      SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS));	/* Make all Safari error conditions fatal except unmapped	 * errors which we make generate interrupts.	 */	err_mask = (BUS_ERROR_BADCMD | BUS_ERROR_SSMDIS |		    BUS_ERROR_BADMA | BUS_ERROR_BADMB |		    BUS_ERROR_BADMC |		    BUS_ERROR_CPU1PS | BUS_ERROR_CPU1PB |		    BUS_ERROR_CPU0PS | BUS_ERROR_CPU0PB |		    BUS_ERROR_CIQTO |		    BUS_ERROR_LPQTO | BUS_ERROR_SFPQTO |		    BUS_ERROR_UFPQTO | BUS_ERROR_APERR |		    BUS_ERROR_BUSERR | BUS_ERROR_TIMEOUT |		    BUS_ERROR_ILL);#if 1	/* XXX Something wrong with some Excalibur systems	 * XXX Sun is shipping.  The behavior on a 2-cpu	 * XXX machine is that both CPU1 parity error bits	 * XXX are set and are immediately set again when	 * XXX their error status bits are cleared.  Just	 * XXX ignore them for now.  -DaveM	 */	err_mask &= ~(BUS_ERROR_CPU1PS | BUS_ERROR_CPU1PB |		      BUS_ERROR_CPU0PS | BUS_ERROR_CPU0PB);#endif	schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_ERRCTRL,		     (SCHIZO_SAFERRCTRL_EN | err_mask));	schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_IRQCTRL,		     (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP)));}static void pbm_config_busmastering(struct pci_pbm_info *pbm){	u8 *addr;	/* Set cache-line size to 64 bytes, this is actually	 * a nop but I do it for completeness.	 */	addr = schizo_pci_config_mkaddr(pbm, pbm->pci_first_busno,					0, PCI_CACHE_LINE_SIZE);	pci_config_write8(addr, 64 / sizeof(u32));	/* Set PBM latency timer to 64 PCI clocks. */	addr = schizo_pci_config_mkaddr(pbm, pbm->pci_first_busno,					0, PCI_LATENCY_TIMER);	pci_config_write8(addr, 64);}static void pbm_scan_bus(struct pci_controller_info *p,			 struct pci_pbm_info *pbm){	struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);	if (!cookie) {		prom_printf("%s: Critical allocation failure.\n", pbm->name);		prom_halt();	}	/* All we care about is the PBM. */	memset(cookie, 0, sizeof(*cookie));	cookie->pbm = pbm;	pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno,				    p->pci_ops,				    pbm);	pci_fixup_host_bridge_self(pbm->pci_bus);	pbm->pci_bus->self->sysdata = cookie;	pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);	pci_record_assignments(pbm, pbm->pci_bus);	pci_assign_unassigned(pbm, pbm->pci_bus);	pci_fixup_irq(pbm, pbm->pci_bus);	pci_determine_66mhz_disposition(pbm, pbm->pci_bus);	pci_setup_busmastering(pbm, pbm->pci_bus);}static void __schizo_scan_bus(struct pci_controller_info *p,			      int chip_type){	if (!p->pbm_B.prom_node || !p->pbm_A.prom_node) {		printk("PCI: Only one PCI bus module of controller found.\n");		printk("PCI: Ignoring entire controller.\n");		return;	}	pbm_config_busmastering(&p->pbm_B);	p->pbm_B.is_66mhz_capable =		prom_getbool(p->pbm_B.prom_node, "66mhz-capable");	pbm_config_busmastering(&p->pbm_A);	p->pbm_A.is_66mhz_capable =		prom_getbool(p->pbm_A.prom_node, "66mhz-capable");	pbm_scan_bus(p, &p->pbm_B);	pbm_scan_bus(p, &p->pbm_A);	/* After the PCI bus scan is complete, we can register	 * the error interrupt handlers.	 */	if (chip_type == PBM_CHIP_TYPE_TOMATILLO)		tomatillo_register_error_handlers(p);	else		schizo_register_error_handlers(p);}static void schizo_scan_bus(struct pci_controller_info *p){	__schizo_scan_bus(p, PBM_CHIP_TYPE_SCHIZO);}static void tomatillo_scan_bus(struct pci_controller_info *p){	__schizo_scan_bus(p, PBM_CHIP_TYPE_TOMATILLO);}static void schizo_base_address_update(struct pci_dev *pdev, int resource){	struct pcidev_cookie *pcp = pdev->sysdata;	struct pci_pbm_info *pbm = pcp->pbm;	struct resource *res, *root;	u32 reg;	int where, size, is_64bit;	res = &pdev->resource[resource];	if (resource < 6) {		where = PCI_BASE_ADDRESS_0 + (resource * 4);	} else if (resource == PCI_ROM_RESOURCE) {		where = pdev->rom_base_reg;	} else {		/* Somebody might have asked allocation of a non-standard resource */		return;	}	is_64bit = 0;	if (res->flags & IORESOURCE_IO)		root = &pbm->io_space;	else {		root = &pbm->mem_space;		if ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK)		    == PCI_BASE_ADDRESS_MEM_TYPE_64)			is_64bit = 1;	}	size = res->end - res->start;	pci_read_config_dword(pdev, where, &reg);	reg = ((reg & size) |	       (((u32)(res->start - root->start)) & ~size));	if (resource == PCI_ROM_RESOURCE) {		reg |= PCI_ROM_ADDRESS_ENABLE;		res->flags |= IORESOURCE_ROM_ENABLE;	}	pci_write_config_dword(pdev, where, reg);	/* This knows that the upper 32-bits of the address	 * must be zero.  Our PCI common layer enforces this.	 */	if (is_64bit)		pci_write_config_dword(pdev, where + 4, 0);}static void schizo_resource_adjust(struct pci_dev *pdev,				   struct resource *res,				   struct resource *root){	res->start += root->start;	res->end += root->start;}/* Use ranges property to determine where PCI MEM, I/O, and Config * space are for this PCI bus module. */static void schizo_determine_mem_io_space(struct pci_pbm_info *pbm){	int i, saw_cfg, saw_mem, saw_io;	saw_cfg = saw_mem = saw_io = 0;	for (i = 0; i < pbm->num_pbm_ranges; i++) {		struct linux_prom_pci_ranges *pr = &pbm->pbm_ranges[i];		unsigned long a;		int type;		type = (pr->child_phys_hi >> 24) & 0x3;		a = (((unsigned long)pr->parent_phys_hi << 32UL) |		     ((unsigned long)pr->parent_phys_lo  <<  0UL));		switch (type) {		case 0:			/* PCI config space, 16MB */			pbm->config_space = a;			saw_cfg = 1;

⌨️ 快捷键说明

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