|
@@ -8,18 +8,21 @@
|
|
|
#include "pci.h"
|
|
|
|
|
|
/*
|
|
|
- * Functions for accessing PCI configuration space with type 1 accesses
|
|
|
+ * Functions for accessing PCI base (first 256 bytes) and extended
|
|
|
+ * (4096 bytes per PCI function) configuration space with type 1
|
|
|
+ * accesses.
|
|
|
*/
|
|
|
|
|
|
#define PCI_CONF1_ADDRESS(bus, devfn, reg) \
|
|
|
- (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3))
|
|
|
+ (0x80000000 | ((reg & 0xF00) << 16) | (bus << 16) \
|
|
|
+ | (devfn << 8) | (reg & 0xFC))
|
|
|
|
|
|
static int pci_conf1_read(unsigned int seg, unsigned int bus,
|
|
|
unsigned int devfn, int reg, int len, u32 *value)
|
|
|
{
|
|
|
unsigned long flags;
|
|
|
|
|
|
- if ((bus > 255) || (devfn > 255) || (reg > 255)) {
|
|
|
+ if ((bus > 255) || (devfn > 255) || (reg > 4095)) {
|
|
|
*value = -1;
|
|
|
return -EINVAL;
|
|
|
}
|
|
@@ -50,7 +53,7 @@ static int pci_conf1_write(unsigned int seg, unsigned int bus,
|
|
|
{
|
|
|
unsigned long flags;
|
|
|
|
|
|
- if ((bus > 255) || (devfn > 255) || (reg > 255))
|
|
|
+ if ((bus > 255) || (devfn > 255) || (reg > 4095))
|
|
|
return -EINVAL;
|
|
|
|
|
|
spin_lock_irqsave(&pci_config_lock, flags);
|
|
@@ -260,10 +263,16 @@ void __init pci_direct_init(int type)
|
|
|
return;
|
|
|
printk(KERN_INFO "PCI: Using configuration type %d for base access\n",
|
|
|
type);
|
|
|
- if (type == 1)
|
|
|
+ if (type == 1) {
|
|
|
raw_pci_ops = &pci_direct_conf1;
|
|
|
- else
|
|
|
+ if (!raw_pci_ext_ops && cpu_has_pci_ext_cfg) {
|
|
|
+ printk(KERN_INFO "PCI: Using configuration type 1 "
|
|
|
+ "for extended access\n");
|
|
|
+ raw_pci_ext_ops = &pci_direct_conf1;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
raw_pci_ops = &pci_direct_conf2;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
int __init pci_direct_probe(void)
|