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

📄 pcilow.c

📁 PCI总线在DOS操作系统下的驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			_asm mov di,reg
			_asm mov ah,PCI_FUNCTION_ID
			_asm mov al,WRITE_CONFIG_WORD		
			_asm mov cx,value
			_asm int 1ah
			_asm mov result,ax
			_asm jc write_fail3
			_asm cmp ah,SUCCESSFUL
			_asm jnz write_fail3
			_asm mov ah,PCI_FUNCTION_ID
			_asm mov al,WRITE_CONFIG_WORD
			_asm add di,2
			_asm mov bx,temp
			_asm mov cx,WORD PTR [value + 2]
			_asm int 1ah
			_asm mov result,ax
			_asm jc write_fail3
			_asm cmp ah,SUCCESSFUL
			_asm jnz write_fail3

		write_fail3:
			
			break;							
	};		

	return (long)((result & 0xff00) >> 8);
}		

long pci_bios_read_config_byte(struct pci_dev *dev, long where, u8 *value)
{
	int result; 
	u32 data;

	if (!value) 
		return -EINVAL;

	result = pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
		PCI_FUNC(dev->devfn), where, 1, &data);

	*value = (u8)data;

	return result;
}

long pci_bios_read_config_word(struct pci_dev *dev, long where, u16 *value)
{
	int result; 
	u32 data;

	if (!value) 
		return -EINVAL;

	result = pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
		PCI_FUNC(dev->devfn), where, 2, &data);

	*value = (u16)data;

	return result;
}

long pci_bios_read_config_dword(struct pci_dev *dev, long where, u32 *value)
{
	if (!value) 
		return -EINVAL;
	
	return pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
		PCI_FUNC(dev->devfn), where, 4, value);
}

long pci_bios_write_config_byte(struct pci_dev *dev, long where, u8 value)
{
	return pci_bios_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
		PCI_FUNC(dev->devfn), where, 1, value);
}

long pci_bios_write_config_word(struct pci_dev *dev, long where, u16 value)
{
	return pci_bios_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
		PCI_FUNC(dev->devfn), where, 2, value);
}

long pci_bios_write_config_dword(struct pci_dev *dev, long where, u32 value)
{
	return pci_bios_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
		PCI_FUNC(dev->devfn), where, 4, value);
}


/*
 * Function table for BIOS32 access
 */

extern struct pci_ops pci_bios_access;


long pci_read_config_byte (struct pci_dev *dev, long pos, u8 *  value) 
{									
	long res;							
									
	if (PCI_byte_BAD) 						
		return BAD_REGISTER_NUMBER;
		                                                       
	local_irq_save(0);
			                                               
	res = dev->bus->ops->read_byte(dev, pos, value);		
									
	local_irq_restore(0);
	                                                               
	return res;																
}

long pci_read_config_word (struct pci_dev *dev, long pos, u16 *  value) 
{									
	long res;							
									
	if (PCI_word_BAD) 						
		return BAD_REGISTER_NUMBER;
		                                                       
	local_irq_save(0);
			                                               
	res = dev->bus->ops->read_word(dev, pos, value);		
									
	local_irq_restore(0);
	                                                               
	return res;																
}

long pci_read_config_dword (struct pci_dev *dev, long pos, u32 *  value) 
{									
	long res;							
									
	if (PCI_dword_BAD) 						
		return BAD_REGISTER_NUMBER;
		                                                       
	local_irq_save(0);
			                                               
	res = dev->bus->ops->read_dword(dev, pos, value);		
									
	local_irq_restore(0);
	                                                               
	return res;															
}

long pci_write_config_byte (struct pci_dev *dev, long pos, u8 value) 
{									
	long res;							
									
	if (PCI_byte_BAD) 						
		return BAD_REGISTER_NUMBER;
		                                                       
	local_irq_save(0);
			                                               
	res = dev->bus->ops->write_byte(dev, pos, value);		
									
	local_irq_restore(0);
	                                                               
	return res;																
}

long pci_write_config_word (struct pci_dev *dev, long pos, u16 value) 
{									
	long res;							
									
	if (PCI_word_BAD) 						
		return BAD_REGISTER_NUMBER;
		                                                       
	local_irq_save(0);
			                                               
	res = dev->bus->ops->write_word(dev, pos, value);		
									
	local_irq_restore(0);
	                                                               
	return res;																
}

long pci_write_config_dword (struct pci_dev *dev, long pos, u32 value) 
{									
	long res;							
									
	if (PCI_dword_BAD) 						
		return BAD_REGISTER_NUMBER;
		                                                       
	local_irq_save(0);
			                                               
	res = dev->bus->ops->write_dword(dev, pos, value);		
									
	local_irq_restore(0);
	                                                               
	return res;															
}

long pci_sanity_check(struct pci_ops *o)
{
	u16 x;
	struct pci_bus bus;		/* Fake bus and device */
	struct pci_dev dev;

	if (pci_probe & PCI_NO_CHECKS)
		return 1;
	bus.number = 0;
	dev.bus = &bus;
	for(dev.devfn=0; dev.devfn < 0x100; dev.devfn++)
		if ((!o->read_word(&dev, PCI_CLASS_DEVICE, &x) &&
		     (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)) ||
		    (!o->read_word(&dev, PCI_VENDOR_ID, &x) &&
		     (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)))
			return 1;
	safe_printf("PCI: Sanity check failed\n");
	return 0;
}

struct pci_ops * pci_check_direct(void)
{
	unsigned long tmp;
	
	local_irq_save(0);
	
	/*
	 * Check if configuration type 1 works.
	 */
	if (pci_probe & PCI_PROBE_CONF1) {
		outb (0x01, 0xCFB);
		tmp = inl (0xCF8);
		outl (0x80000000, 0xCF8);
		if (inl (0xCF8) == 0x80000000 &&
		    pci_sanity_check(&pci_direct_conf1)) {
			outl (tmp, 0xCF8);
			local_irq_restore(0);
			return &pci_direct_conf1;
		}
		outl (tmp, 0xCF8);
	}

	/*
	 * Check if configuration type 2 works.
	 */
	if (pci_probe & PCI_PROBE_CONF2) {
		outb (0x00, 0xCFB);
		outb (0x00, 0xCF8);
		outb (0x00, 0xCFA);
		if (inb (0xCF8) == 0x00 && inb (0xCFA) == 0x00 &&
		    pci_sanity_check(&pci_direct_conf2)) {
			local_irq_restore(0);
			safe_printf("PCI: Using configuration type 2\n");
			return &pci_direct_conf2;
		}
	}

	local_irq_restore(0);
	return NULL;
}

void pcibios_config_init(void)
{
	if ((pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2)) 
		&& (pci_root_ops = pci_check_direct())) {
		if (pci_root_ops == &pci_direct_conf1) {
			pci_config_read = pci_conf1_read;
			pci_config_write = pci_conf1_write;
		}
		else {
			pci_config_read = pci_conf2_read;
			pci_config_write = pci_conf2_write;
		}
		
		return;
	}
	
	if ((pci_probe & PCI_PROBE_BIOS) 
		&& ((pci_root_ops = pci_find_bios()))) {
		pci_probe |= PCI_BIOS_SORT;
		pci_bios_present = 1;
		pci_config_read = pci_bios_read;
		pci_config_write = pci_bios_write;
	}
	
	return;
}

void pcibios_init(void)
{
	if (!pci_root_ops)
		pcibios_config_init();
	if (!pci_root_ops) {
		safe_printf("PCI: System does not support PCI\n");
		return;
	}

	safe_printf("PCI: Probing PCI hardware\n");

	pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);

	pcibios_irq_init();
	pcibios_fixup_peer_bridges();
	pcibios_fixup_irqs();
	pcibios_resource_survey();

	if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
			pcibios_sort();
}

struct pci_ops * pci_find_bios(void)
{
	_asm mov ah,PCI_FUNCTION_ID
	_asm mov al,PCI_BIOS_PRESENT
	_asm int 1ah
	_asm jc check_fail
	_asm cmp ah,SUCCESSFUL
	_asm jnz check_fail
	_asm cmp dx,PCIBIOS_SIGNATURE
	_asm jnz check_fail
	
	return &pci_bios_access;
	
	check_fail:		

	return NULL;
}

long pci_bios_find_device (unsigned short vendor, unsigned short device_id,
					unsigned short index, unsigned char far * bus, 
					unsigned char far * device_fn)
{
	unsigned short bx1;
	unsigned short res;

	_asm push si
	_asm mov ah,PCI_FUNCTION_ID
	_asm mov al,FIND_PCI_DEVICE
	_asm mov cx,device_id
	_asm mov dx,vendor
	_asm mov si,index
	_asm int 1ah
	_asm pop si
	_asm mov res,ax
	_asm jc find_fail
	_asm cmp ah,SUCCESSFUL
	_asm jnz find_fail
	_asm mov bx1,bx
	_asm jmp find_ok

	find_fail:

		if(!(res & 0xff00))
			return 0xff00L;
		else
			return (long)(res & 0xff00) >> 8;

	find_ok:	

		*bus = (bx1 >> 8) & 0xff;
		*device_fn = bx1 & 0xff;

		return (long) (res & 0xff00) >> 8;
}

⌨️ 快捷键说明

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