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

📄 pci-hplj.c

📁 优龙2410linux2.6.8内核源代码
💻 C
字号:
/* * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * * SNI specific PCI support for RM200/RM300. * * Copyright (C) 1997 - 2000 Ralf Baechle */#include <linux/kernel.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/types.h>#include <asm/byteorder.h>#include <asm/pci_channel.h>#include <asm/hp-lj/asic.h>static volatile u32 *pci_config_address_reg = (volatile u32 *) 0xfdead000;static volatile u32 *pci_config_data_reg = (volatile u32 *) 0xfdead000;#define cfgaddr(dev, where) (((dev->bus->number & 0xff) << 0x10) |  \                             ((dev->devfn & 0xff) << 0x08) |        \                             (where & 0xfc))/* * We can't address 8 and 16 bit words directly.  Instead we have to * read/write a 32bit word and mask/modify the data we actually want. */static int pcimt_read_config_byte(struct pci_dev *dev,				  int where, unsigned char *val){	*pci_config_address_reg = cfgaddr(dev, where);	*val =	    (le32_to_cpu(*pci_config_data_reg) >> ((where & 3) << 3)) &	    0xff;	//printk("pci_read_byte 0x%x == 0x%x\n", where, *val);	return PCIBIOS_SUCCESSFUL;}static int pcimt_read_config_word(struct pci_dev *dev,				  int where, unsigned short *val){	if (where & 1)		return PCIBIOS_BAD_REGISTER_NUMBER;	*pci_config_address_reg = cfgaddr(dev, where);	*val =	    (le32_to_cpu(*pci_config_data_reg) >> ((where & 3) << 3)) &	    0xffff;	//printk("pci_read_word 0x%x == 0x%x\n", where, *val);	return PCIBIOS_SUCCESSFUL;}int pcimt_read_config_dword(struct pci_dev *dev,			    int where, unsigned int *val){	if (where & 3)		return PCIBIOS_BAD_REGISTER_NUMBER;	*pci_config_address_reg = cfgaddr(dev, where);	*val = le32_to_cpu(*pci_config_data_reg);	//printk("pci_read_dword 0x%x == 0x%x\n", where, *val);	return PCIBIOS_SUCCESSFUL;}static int pcimt_write_config_byte(struct pci_dev *dev,				   int where, unsigned char val){	*pci_config_address_reg = cfgaddr(dev, where);	*(volatile u8 *) (((int) pci_config_data_reg) + (where & 3)) = val;	//printk("pci_write_byte 0x%x = 0x%x\n", where, val);	return PCIBIOS_SUCCESSFUL;}static int pcimt_write_config_word(struct pci_dev *dev,				   int where, unsigned short val){	if (where & 1)		return PCIBIOS_BAD_REGISTER_NUMBER;	*pci_config_address_reg = cfgaddr(dev, where);	*(volatile u16 *) (((int) pci_config_data_reg) + (where & 2)) =	    le16_to_cpu(val);	//printk("pci_write_word 0x%x = 0x%x\n", where, val);	return PCIBIOS_SUCCESSFUL;}int pcimt_write_config_dword(struct pci_dev *dev,			     int where, unsigned int val){	if (where & 3)		return PCIBIOS_BAD_REGISTER_NUMBER;	*pci_config_address_reg = cfgaddr(dev, where);	*pci_config_data_reg = le32_to_cpu(val);	//printk("pci_write_dword 0x%x = 0x%x\n", where, val);	return PCIBIOS_SUCCESSFUL;}struct pci_ops hp_pci_ops = {	pcimt_read_config_byte,	pcimt_read_config_word,	pcimt_read_config_dword,	pcimt_write_config_byte,	pcimt_write_config_word,	pcimt_write_config_dword};struct pci_controller hp_controller = {	.pci_ops	= &hp_pci_ops,	.io_resource	= &ioport_resource,	.mem_resource	= &iomem_resource,};void __init pcibios_fixup_irqs(void){	struct pci_dev *dev = NULL;	int slot_num;	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {		slot_num = PCI_SLOT(dev->devfn);		switch (slot_num) {		case 2:			dev->irq = 3;			break;		case 3:			dev->irq = 4;			break;		case 4:			dev->irq = 5;			break;		default:			break;		}	}}#define IO_MEM_LOGICAL_START   0x3e000000#define IO_MEM_LOGICAL_END     0x3fefffff#define IO_PORT_LOGICAL_START  0x3ff00000#define IO_PORT_LOGICAL_END    0x3fffffff#define IO_MEM_VIRTUAL_OFFSET  0xb0000000#define IO_PORT_VIRTUAL_OFFSET 0xb0000000#define ONE_MEG   (1024 * 1024)void __init pci_setup(void){	u32 pci_regs_base_offset = 0xfdead000;	switch (GetAsicId()) {	case AndrosAsic:		pci_regs_base_offset = 0xbff80000;		break;	case HarmonyAsic:		pci_regs_base_offset = 0xbff70000;		break;	default:		printk("ERROR: PCI does not support %s Asic\n",		       GetAsicName());		while (1);		break;	}	// set bus stat/command reg	// REVIST this setting may need vary depending on the hardware	*((volatile unsigned int *) (pci_regs_base_offset | 0x0004)) =	    0x38000007;	iomem_resource.start =	    IO_MEM_LOGICAL_START + IO_MEM_VIRTUAL_OFFSET;	iomem_resource.end = IO_MEM_LOGICAL_END + IO_MEM_VIRTUAL_OFFSET;	ioport_resource.start =	    IO_PORT_LOGICAL_START + IO_PORT_VIRTUAL_OFFSET;	ioport_resource.end = IO_PORT_LOGICAL_END + IO_PORT_VIRTUAL_OFFSET;	// KLUDGE (mips_io_port_base is screwed up, we've got to work around it here)	// by letting both low (illegal) and high (legal) addresses appear in pci io space	ioport_resource.start = 0x0;	set_io_port_base(IO_PORT_LOGICAL_START + IO_PORT_VIRTUAL_OFFSET);	// map the PCI address space	// global map - all levels & processes can access	// except that the range is outside user space	// parameters: lo0, lo1, hi, pagemask	// lo indicates physical page, hi indicates virtual address	add_wired_entry((IO_MEM_LOGICAL_START >> 6) | 0x17,			((IO_MEM_LOGICAL_START +			  (16 * ONE_MEG)) >> 6) | 0x17, 0xee000000,			PM_16M);	// These are used in pci r/w routines so need to preceed bus scan	pci_config_data_reg = (u32 *) (((u32) mips_io_port_base) | 0xcfc);	pci_config_address_reg =	    (u32 *) (((u32) pci_regs_base_offset) | 0xcf8);}

⌨️ 快捷键说明

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