示例#1
0
文件: mmconfig_32.c 项目: 08opt/linux
static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
			   unsigned int devfn, int reg, int len, u32 value)
{
	unsigned long flags;
	u32 base;

	if ((bus > 255) || (devfn > 255) || (reg > 4095))
		return -EINVAL;

	base = get_base_addr(seg, bus, devfn);
	if (!base)
		return -EINVAL;

	raw_spin_lock_irqsave(&pci_config_lock, flags);

	pci_exp_set_dev_base(base, bus, devfn);

	switch (len) {
	case 1:
		mmio_config_writeb(mmcfg_virt_addr + reg, value);
		break;
	case 2:
		mmio_config_writew(mmcfg_virt_addr + reg, value);
		break;
	case 4:
		mmio_config_writel(mmcfg_virt_addr + reg, value);
		break;
	}
	raw_spin_unlock_irqrestore(&pci_config_lock, flags);

	return 0;
}
示例#2
0
文件: mmconfig_32.c 项目: 08opt/linux
static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
			  unsigned int devfn, int reg, int len, u32 *value)
{
	unsigned long flags;
	u32 base;

	if ((bus > 255) || (devfn > 255) || (reg > 4095)) {
err:		*value = -1;
		return -EINVAL;
	}

	base = get_base_addr(seg, bus, devfn);
	if (!base)
		goto err;

	raw_spin_lock_irqsave(&pci_config_lock, flags);

	pci_exp_set_dev_base(base, bus, devfn);

	switch (len) {
	case 1:
		*value = mmio_config_readb(mmcfg_virt_addr + reg);
		break;
	case 2:
		*value = mmio_config_readw(mmcfg_virt_addr + reg);
		break;
	case 4:
		*value = mmio_config_readl(mmcfg_virt_addr + reg);
		break;
	}
	raw_spin_unlock_irqrestore(&pci_config_lock, flags);

	return 0;
}
示例#3
0
static int pci_mmcfg_write(int seg, int bus, int devfn, int reg, int len, u32 value)
{
	unsigned long flags;

	if ((bus > 255) || (devfn > 255) || (reg > 4095)) 
		return -EINVAL;

	spin_lock_irqsave(&pci_config_lock, flags);

	pci_exp_set_dev_base(bus, devfn);

	switch (len) {
	case 1:
		writeb(value, mmcfg_virt_addr + reg);
		break;
	case 2:
		writew(value, mmcfg_virt_addr + reg);
		break;
	case 4:
		writel(value, mmcfg_virt_addr + reg);
		break;
	}

	spin_unlock_irqrestore(&pci_config_lock, flags);

	return 0;
}
示例#4
0
static int pci_mmcfg_read(int seg, int bus, int devfn, int reg, int len, u32 *value)
{
	unsigned long flags;

	if (!value || (bus > 255) || (devfn > 255) || (reg > 4095))
		return -EINVAL;

	spin_lock_irqsave(&pci_config_lock, flags);

	pci_exp_set_dev_base(bus, devfn);

	switch (len) {
	case 1:
		*value = readb(mmcfg_virt_addr + reg);
		break;
	case 2:
		*value = readw(mmcfg_virt_addr + reg);
		break;
	case 4:
		*value = readl(mmcfg_virt_addr + reg);
		break;
	}

	spin_unlock_irqrestore(&pci_config_lock, flags);

	return 0;
}
示例#5
0
文件: mmconfig.c 项目: ivucica/linux
/* K8 systems have some devices (typically in the builtin northbridge)
   that are only accessible using type1
   Normally this can be expressed in the MCFG by not listing them
   and assigning suitable _SEGs, but this isn't implemented in some BIOS.
   Instead try to discover all devices on bus 0 that are unreachable using MM
   and fallback for them. */
static __init void unreachable_devices(void)
{
	int i, k;
	unsigned long flags;

	for (k = 0; k < MAX_CHECK_BUS; k++) {
		for (i = 0; i < 32; i++) {
			u32 val1;
			u32 addr;

			pci_conf1_read(0, k, PCI_DEVFN(i, 0), 0, 4, &val1);
			if (val1 == 0xffffffff)
				continue;

			/* Locking probably not needed, but safer */
			spin_lock_irqsave(&pci_config_lock, flags);
			addr = get_base_addr(0, k, PCI_DEVFN(i, 0));
			if (addr != 0)
				pci_exp_set_dev_base(addr, k, PCI_DEVFN(i, 0));
			if (addr == 0 ||
			    readl((u32 __iomem *)mmcfg_virt_addr) != val1) {
				set_bit(i + 32*k, fallback_slots);
				printk(KERN_NOTICE
			"PCI: No mmconfig possible on %x:%x\n", k, i);
			}
			spin_unlock_irqrestore(&pci_config_lock, flags);
		}
	}
}
示例#6
0
/* K8 systems have some devices (typically in the builtin northbridge)
   that are only accessible using type1
   Normally this can be expressed in the MCFG by not listing them
   and assigning suitable _SEGs, but this isn't implemented in some BIOS.
   Instead try to discover all devices on bus 0 that are unreachable using MM
   and fallback for them.
   We only do this for bus 0/seg 0 */
static __init void unreachable_devices(void)
{
	int i;
	unsigned long flags;

	for (i = 0; i < 32; i++) {
		u32 val1;
		u32 addr;

		pci_conf1_read(0, 0, PCI_DEVFN(i, 0), 0, 4, &val1);
		if (val1 == 0xffffffff)
			continue;

		/* Locking probably not needed, but safer */
		spin_lock_irqsave(&pci_config_lock, flags);
		addr = get_base_addr(0, 0, PCI_DEVFN(i, 0));
		if (addr != 0)
			pci_exp_set_dev_base(addr, 0, PCI_DEVFN(i, 0));
		if (addr == 0 || readl((u32 __iomem *)mmcfg_virt_addr) != val1)
			set_bit(i, fallback_slots);
		spin_unlock_irqrestore(&pci_config_lock, flags);
	}
}