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

📄 ops-pmcmsp.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
 * *  FUNCTION: msp_pcibios_config_access *  _________________________________________________________________________ * *  DESCRIPTION: Performs a PCI configuration access (rd or wr), then *               checks that the access succeeded by querying MSP7120's *               PCI status bits. * *  INPUTS: *               access_type  - kind of PCI configuration cycle to perform *                              (read or write). Legal values are *                              PCI_ACCESS_WRITE and PCI_ACCESS_READ. * *               bus          - pointer to the bus number of the device to *                              be targetted for the configuration cycle. *                              The only element of the pci_bus structure *                              used is bus->number. This argument determines *                              if the configuration access will be Type 0 or *                              Type 1. Since MSP7120 assumes itself to be the *                              PCI Host, any non-zero bus->number generates *                              a Type 1 access. * *               devfn        - this is an 8-bit field. The lower three bits *                              specify the function number of the device to *                              be targetted for the configuration cycle, with *                              all three-bit combinations being legal. The *                              upper five bits specify the device number, *                              with legal values being 10 to 31. * *               where        - address within the Configuration Header *                              space to access. * *               data         - for write accesses, contains the data to *                              write. * *  OUTPUTS: *               data         - for read accesses, contains the value read. * *  RETURNS:     PCIBIOS_SUCCESSFUL  - success *               -1                  - access failure * ****************************************************************************/int msp_pcibios_config_access(unsigned char access_type,				struct pci_bus *bus,				unsigned int devfn,				unsigned char where,				u32 *data){	struct msp_pci_regs *preg = (void *)PCI_BASE_REG;	unsigned char bus_num = bus->number;	unsigned char dev_fn = (unsigned char)devfn;	unsigned long flags;	unsigned long intr;	unsigned long value;	static char pciirqflag;#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)	unsigned int	vpe_status;#endif#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)	if (proc_init == 0) {		pci_proc_init();		proc_init = ~0;	}#endif /* CONFIG_PROC_FS && PCI_COUNTERS */	/*	 * Just the first time this function invokes, allocate	 * an interrupt line for PCI host status interrupts. The	 * allocation assigns an interrupt handler to the interrupt.	 */	if (pciirqflag == 0) {		request_irq(MSP_INT_PCI,/* Hardcoded internal MSP7120 wiring */				bpci_interrupt,				IRQF_SHARED | IRQF_DISABLED,				"PMC MSP PCI Host",				preg);		pciirqflag = ~0;	}#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)	local_irq_save(flags);	vpe_status = dvpe();#else	spin_lock_irqsave(&bpci_lock, flags);#endif	/*	 * Clear PCI cause register bits.	 *	 * In Polo, the PCI Host had a dedicated DMA called the	 * Block Copy (not to be confused with the general purpose Block	 * Copy Engine block). There appear to have been special interrupts	 * for this Block Copy, called Block Copy 0 Fault (BC0F) and	 * Block Copy 1 Fault (BC1F). MSP4200 and MSP7120 don't have this	 * dedicated Block Copy block, so these two interrupts are now	 * marked reserved. In case the  Block Copy is resurrected in a	 * future design, maintain the code that treats these two interrupts	 * specially.	 *	 * Write to clear all interrupts in the PCI status register, aside	 * from BC0F and BC1F.	 */	preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);	/* Setup address that is to appear on PCI bus */	preg->config_addr = BPCI_CFGADDR_ENABLE	|		(bus_num << BPCI_CFGADDR_BUSNUM_SHF) |		(dev_fn << BPCI_CFGADDR_FUNCTNUM_SHF) |		(where & 0xFC);	/* IF access is a PCI configuration write */	if (access_type == PCI_ACCESS_WRITE) {		value = cpu_to_le32(*data);		*PCI_CONFIG_SPACE_REG = value;	} else {		/* ELSE access is a PCI configuration read */		value = le32_to_cpu(*PCI_CONFIG_SPACE_REG);		*data = value;	}	/*	 * Check if the PCI configuration cycle (rd or wr) succeeded, by	 * checking the status bits for errors like master or target abort.	 */	intr = preg->if_status;	/* Clear config access */	preg->config_addr = 0;	/* IF error occurred */	if (intr & ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F)) {		/* Clear status bits */		preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)		evpe(vpe_status);		local_irq_restore(flags);#else		spin_unlock_irqrestore(&bpci_lock, flags);#endif		return -1;	}#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)	evpe(vpe_status);	local_irq_restore(flags);#else	spin_unlock_irqrestore(&bpci_lock, flags);#endif	return PCIBIOS_SUCCESSFUL;}/***************************************************************************** * *  FUNCTION: msp_pcibios_read_config_byte *  _________________________________________________________________________ * *  DESCRIPTION: Read a byte from PCI configuration address spac *               Since the hardware can't address 8 bit chunks *               directly, read a 32-bit chunk, then mask off extraneous *               bits. * *  INPUTS       bus    - structure containing attributes for the PCI bus *                        that the read is destined for. *               devfn  - device/function combination that the read is *                        destined for. *               where  - register within the Configuration Header space *                        to access. * *  OUTPUTS      val    - read data * *  RETURNS:     PCIBIOS_SUCCESSFUL  - success *               -1                  - read access failure * ****************************************************************************/static intmsp_pcibios_read_config_byte(struct pci_bus *bus,				unsigned int devfn,				int where,				u32 *val){	u32 data = 0;	/*	 * If the config access did not complete normally (e.g., underwent	 * master abort) do the PCI compliant thing, which is to supply an	 * all ones value.	 */	if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,					where, &data)) {		*val = 0xFFFFFFFF;		return -1;	}	*val = (data >> ((where & 3) << 3)) & 0x0ff;	return PCIBIOS_SUCCESSFUL;}/***************************************************************************** * *  FUNCTION: msp_pcibios_read_config_word *  _________________________________________________________________________ * *  DESCRIPTION: Read a word (16 bits) from PCI configuration address space. *               Since the hardware can't address 16 bit chunks *               directly, read a 32-bit chunk, then mask off extraneous *               bits. * *  INPUTS       bus    - structure containing attributes for the PCI bus *                        that the read is destined for. *               devfn  - device/function combination that the read is *                        destined for. *               where  - register within the Configuration Header space *                        to access. * *  OUTPUTS      val    - read data * *  RETURNS:     PCIBIOS_SUCCESSFUL           - success *               PCIBIOS_BAD_REGISTER_NUMBER  - bad register address *               -1                           - read access failure * ****************************************************************************/static intmsp_pcibios_read_config_word(struct pci_bus *bus,				unsigned int devfn,				int where,				u32 *val){	u32 data = 0;	/* if (where & 1) */	/* Commented out non-compliant code.				 * Should allow word access to configuration				 * registers, with only exception being when				 * the word access would wrap around into				 * the next dword.				 */	if ((where & 3) == 3) {		*val = 0xFFFFFFFF;		return PCIBIOS_BAD_REGISTER_NUMBER;	}	/*	 * If the config access did not complete normally (e.g., underwent	 * master abort) do the PCI compliant thing, which is to supply an	 * all ones value.	 */	if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,					where, &data)) {		*val = 0xFFFFFFFF;		return -1;	}	*val = (data >> ((where & 3) << 3)) & 0x0ffff;	return PCIBIOS_SUCCESSFUL;}/***************************************************************************** * *  FUNCTION: msp_pcibios_read_config_dword *  _________________________________________________________________________ * *  DESCRIPTION: Read a double word (32 bits) from PCI configuration *               address space. * *  INPUTS       bus    - structure containing attributes for the PCI bus *                        that the read is destined for. *               devfn  - device/function combination that the read is *                        destined for. *               where  - register within the Configuration Header space *                        to access. * *  OUTPUTS      val    - read data * *  RETURNS:     PCIBIOS_SUCCESSFUL           - success *               PCIBIOS_BAD_REGISTER_NUMBER  - bad register address *               -1                           - read access failure * ****************************************************************************/static intmsp_pcibios_read_config_dword(struct pci_bus *bus,				unsigned int devfn,				int where,				u32 *val){	u32 data = 0;	/* Address must be dword aligned. */	if (where & 3) {		*val = 0xFFFFFFFF;		return PCIBIOS_BAD_REGISTER_NUMBER;	}	/*	 * If the config access did not complete normally (e.g., underwent	 * master abort) do the PCI compliant thing, which is to supply an	 * all ones value.	 */	if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,					where, &data)) {		*val = 0xFFFFFFFF;		return -1;	}	*val = data;	return PCIBIOS_SUCCESSFUL;}/***************************************************************************** * *  FUNCTION: msp_pcibios_write_config_byte *  _________________________________________________________________________ * *  DESCRIPTION: Write a byte to PCI configuration address space. *               Since the hardware can't address 8 bit chunks *               directly, a read-modify-write is performed. * *  INPUTS       bus    - structure containing attributes for the PCI bus *                        that the write is destined for. *               devfn  - device/function combination that the write is *                        destined for. *               where  - register within the Configuration Header space *                        to access. *               val    - value to write * *  OUTPUTS      none *

⌨️ 快捷键说明

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