diff -urN wt1-721/arch/i386/config.in wt1/arch/i386/config.in --- wt1-721/arch/i386/config.in Fri Aug 13 22:13:41 2004 +++ wt1/arch/i386/config.in Fri Aug 13 22:14:00 2004 @@ -338,12 +338,16 @@ choice ' PCI access mode' \ "BIOS CONFIG_PCI_GOBIOS \ Direct CONFIG_PCI_GODIRECT \ + MMConfig CONFIG_PCI_GOMMCONFIG \ Any CONFIG_PCI_GOANY" Any if [ "$CONFIG_PCI_GOBIOS" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then define_bool CONFIG_PCI_BIOS y fi if [ "$CONFIG_PCI_GODIRECT" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then define_bool CONFIG_PCI_DIRECT y + fi + if [ "$CONFIG_PCI_GOMMCONFIG" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then + define_bool CONFIG_PCI_MMCONFIG y fi fi bool 'ISA bus support' CONFIG_ISA diff -urN wt1-721/arch/i386/kernel/Makefile wt1/arch/i386/kernel/Makefile --- wt1-721/arch/i386/kernel/Makefile Fri Aug 13 22:13:41 2004 +++ wt1/arch/i386/kernel/Makefile Fri Aug 13 22:14:00 2004 @@ -31,6 +31,10 @@ endif endif +ifdef CONFIG_PCI_MMCONFIG +obj-y += mmconfig.o +endif + obj-$(CONFIG_MCA) += mca.o obj-$(CONFIG_MTRR) += mtrr.o obj-$(CONFIG_X86_MSR) += msr.o diff -urN wt1-721/arch/i386/kernel/mmconfig.c wt1/arch/i386/kernel/mmconfig.c --- wt1-721/arch/i386/kernel/mmconfig.c Thu Jan 1 01:00:00 1970 +++ wt1/arch/i386/kernel/mmconfig.c Fri Aug 13 22:14:00 2004 @@ -0,0 +1,178 @@ +/* + * mmconfig.c - Low-level direct PCI config space access via MMCONFIG + */ + +#include +#include +#include "pci-i386.h" + +/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ +extern u32 pci_mmcfg_base_addr; + +#define mmcfg_virt_addr (fix_to_virt(FIX_PCIE_MCFG)) + +/* The base address of the last MMCONFIG device accessed */ +static u32 mmcfg_last_accessed_device; + +/* + * Functions for accessing PCI configuration space with MMCONFIG accesses + */ + +static inline void pci_exp_set_dev_base(int bus, int devfn) +{ + u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12); + if (dev_base != mmcfg_last_accessed_device) { + mmcfg_last_accessed_device = dev_base; + set_fixmap(FIX_PCIE_MCFG, dev_base); + } +} + +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; +} + +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; + } + + /* Dummy read to flush PCI write */ + readl(mmcfg_virt_addr); + + spin_unlock_irqrestore(&pci_config_lock, flags); + + return 0; +} + +static int pci_mmcfg_read_config_byte(struct pci_dev *dev, int where, u8 *value) +{ + int result; + u32 data; + + result = pci_mmcfg_read(0, dev->bus->number, dev->devfn, + where, 1, &data); + + *value = (u8)data; + + return result; +} + +static int pci_mmcfg_read_config_word(struct pci_dev *dev, int where, u16 *value) +{ + int result; + u32 data; + + result = pci_mmcfg_read(0, dev->bus->number, dev->devfn, + where, 2, &data); + + *value = (u16)data; + + return result; +} + +static int pci_mmcfg_read_config_dword(struct pci_dev *dev, int where, u32 *value) +{ + return pci_mmcfg_read(0, dev->bus->number, dev->devfn, + where, 4, value); +} + +static int pci_mmcfg_write_config_byte(struct pci_dev *dev, int where, u8 value) +{ + return pci_mmcfg_write(0, dev->bus->number, dev->devfn, + where, 1, value); +} + +static int pci_mmcfg_write_config_word(struct pci_dev *dev, int where, u16 value) +{ + return pci_mmcfg_write(0, dev->bus->number, dev->devfn, + where, 2, value); +} + +static int pci_mmcfg_write_config_dword(struct pci_dev *dev, int where, u32 value) +{ + return pci_mmcfg_write(0, dev->bus->number, dev->devfn, + where, 4, value); +} + +static struct pci_ops pci_mmcfg = { + pci_mmcfg_read_config_byte, + pci_mmcfg_read_config_word, + pci_mmcfg_read_config_dword, + pci_mmcfg_write_config_byte, + pci_mmcfg_write_config_word, + pci_mmcfg_write_config_dword +}; + +struct pci_ops * __devinit pci_mmcfg_init(void) +{ + if ((pci_probe & PCI_PROBE_MMCONF) == 0) + { + goto out; + } + if (!pci_mmcfg_base_addr) + { + goto out; + } + + printk(KERN_INFO "PCI: Using MMCONFIG\n"); + pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; + + return &pci_mmcfg; + +out: + return NULL; +} + +int pci_mcfg_read(int seg, int bus, int dev, int fn, int reg, int len, + u32 *value) +{ + pci_mmcfg_read(seg, bus, PCI_DEVFN(dev, fn), reg, len, value); +} + +int pci_mcfg_write(int seg, int bus, int dev, int fn, int reg, int len, + u32 *value) +{ + pci_mmcfg_write(seg, bus, PCI_DEVFN(dev, fn), reg, len, value); +} diff -urN wt1-721/arch/i386/kernel/pci-i386.h wt1/arch/i386/kernel/pci-i386.h --- wt1-721/arch/i386/kernel/pci-i386.h Fri Aug 13 22:13:41 2004 +++ wt1/arch/i386/kernel/pci-i386.h Fri Aug 13 22:14:00 2004 @@ -15,6 +15,8 @@ #define PCI_PROBE_BIOS 0x0001 #define PCI_PROBE_CONF1 0x0002 #define PCI_PROBE_CONF2 0x0004 +#define PCI_PROBE_MMCONF 0x0008 +#define PCI_PROBE_MASK 0x000f #define PCI_NO_SORT 0x0100 #define PCI_BIOS_SORT 0x0200 #define PCI_NO_CHECKS 0x0400 @@ -23,6 +25,7 @@ #define PCI_ASSIGN_ALL_BUSSES 0x4000 extern unsigned int pci_probe; +extern spinlock_t pci_config_lock; /* pci-i386.c */ @@ -69,3 +72,10 @@ void pcibios_irq_init(void); void pcibios_fixup_irqs(void); void pcibios_enable_irq(struct pci_dev *dev); + +/* mmconfig.c */ +int pci_mcfg_read(int seg, int bus, int dev, int fn, int reg, int len, + u32 *value); +int pci_mcfg_write(int seg, int bus, int dev, int fn, int reg, int len, + u32 *value); +struct pci_ops * __devinit pci_mmcfg_init(void); diff -urN wt1-721/arch/i386/kernel/pci-pc.c wt1/arch/i386/kernel/pci-pc.c --- wt1-721/arch/i386/kernel/pci-pc.c Fri Aug 13 22:13:41 2004 +++ wt1/arch/i386/kernel/pci-pc.c Fri Aug 13 22:14:00 2004 @@ -21,7 +21,8 @@ #include "pci-i386.h" -unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2; +unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | + PCI_PROBE_MMCONF; int pcibios_last_bus = -1; struct pci_bus *pci_root_bus = NULL; @@ -46,7 +47,7 @@ * This interrupt-safe spinlock protects all accesses to PCI * configuration space. */ -static spinlock_t pci_config_lock = SPIN_LOCK_UNLOCKED; +spinlock_t pci_config_lock = SPIN_LOCK_UNLOCKED; /* @@ -1455,6 +1456,33 @@ } #endif +#ifdef CONFIG_PCI_MMCONFIG + pci_root_ops = pci_mmcfg_init(); + if (pci_root_ops){ + pci_config_read = pci_mcfg_read; + pci_config_write = pci_mcfg_write; + return; + } +#ifdef CONFIG_PCI_DIRECT + /* + * PCI Express option is enabled in NON-PCI Express + * platforms. Reset the PCI root ops + */ + if ((pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2)) + && (tmp = pci_check_direct())) { + pci_root_ops = tmp; + 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; + } + } +#endif +#endif + return; } @@ -1529,6 +1557,12 @@ } else if (!strcmp(str, "conf2")) { pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS; + return NULL; + } +#endif +#ifdef CONFIG_PCI_MMCONFIG + else if (!strcmp(str, "nommconf")) { + pci_probe &= ~PCI_PROBE_MMCONF; return NULL; } #endif diff -urN wt1-721/arch/x86_64/config.in wt1/arch/x86_64/config.in --- wt1-721/arch/x86_64/config.in Fri Aug 13 22:13:41 2004 +++ wt1/arch/x86_64/config.in Fri Aug 13 22:14:00 2004 @@ -95,7 +95,16 @@ bool 'Networking support' CONFIG_NET bool 'PCI support' CONFIG_PCI if [ "$CONFIG_PCI" = "y" ]; then - define_bool CONFIG_PCI_DIRECT y + choice ' PCI access mode' \ + "Direct CONFIG_PCI_GODIRECT \ + MMConfig CONFIG_PCI_GOMMCONFIG \ + Any CONFIG_PCI_GOANY" Any + if [ "$CONFIG_PCI_GODIRECT" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then + define_bool CONFIG_PCI_DIRECT y + fi + if [ "$CONFIG_PCI_GOMMCONFIG" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then + define_bool CONFIG_PCI_MMCONFIG y + fi fi source drivers/pci/Config.in diff -urN wt1-721/arch/x86_64/kernel/Makefile wt1/arch/x86_64/kernel/Makefile --- wt1-721/arch/x86_64/kernel/Makefile Fri Aug 13 22:13:41 2004 +++ wt1/arch/x86_64/kernel/Makefile Fri Aug 13 22:14:00 2004 @@ -22,6 +22,10 @@ pci-dma.o x8664_ksyms.o i387.o syscall.o vsyscall.o \ setup64.o e820.o warmreboot.o +ifdef CONFIG_PCI_MMCONFIG +obj-y += mmconfig.o +endif + ifdef CONFIG_PCI obj-y += pci-x86_64.o obj-y += pci-pc.o pci-irq.o diff -urN wt1-721/arch/x86_64/kernel/mmconfig.c wt1/arch/x86_64/kernel/mmconfig.c --- wt1-721/arch/x86_64/kernel/mmconfig.c Thu Jan 1 01:00:00 1970 +++ wt1/arch/x86_64/kernel/mmconfig.c Fri Aug 13 22:14:00 2004 @@ -0,0 +1,170 @@ +/* + * mmconfig.c - Low-level direct PCI config space access via MMCONFIG + */ + +#include +#include +#include "pci-x86_64.h" + +/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ +extern u32 pci_mmcfg_base_addr; + +#define mmcfg_virt_addr (fix_to_virt(FIX_PCIE_MCFG)) + +/* The base address of the last MMCONFIG device accessed */ +static u32 mmcfg_last_accessed_device; + +/* + * Functions for accessing PCI configuration space with MMCONFIG accesses + */ + +static inline void pci_exp_set_dev_base(int bus, int devfn) +{ + u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12); + if (dev_base != mmcfg_last_accessed_device) { + mmcfg_last_accessed_device = dev_base; + set_fixmap(FIX_PCIE_MCFG, dev_base); + } +} + +static int pci_mmcfg_read(int seg, int bus, int devfn, int reg, int len, + u32 *value) +{ + if (!value || (bus > 255) || (devfn > 255) || (reg > 4095)) + return -EINVAL; + + 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; + } + + return 0; +} + +static int pci_mmcfg_write(int seg, int bus, int devfn, int reg, int len, + u32 value) +{ + if ((bus > 255) || (devfn > 255) || (reg > 4095)) + return -EINVAL; + + 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; + } + + /* Dummy read to flush PCI write */ + readl(mmcfg_virt_addr); + + return 0; +} + +static int pci_mmcfg_read_config_byte(struct pci_dev *dev, int where, + u8 *value) +{ + int result; + u32 data; + + result = pci_mmcfg_read(0, dev->bus->number, dev->devfn, + where, 1, &data); + + *value = (u8)data; + + return result; +} + +static int pci_mmcfg_read_config_word(struct pci_dev *dev, int where, + u16 *value) +{ + int result; + u32 data; + + result = pci_mmcfg_read(0, dev->bus->number, dev->devfn, + where, 2, &data); + + *value = (u16)data; + + return result; +} + +static int pci_mmcfg_read_config_dword(struct pci_dev *dev, int where, + u32 *value) +{ + return pci_mmcfg_read(0, dev->bus->number, dev->devfn, + where, 4, value); +} + +static int pci_mmcfg_write_config_byte(struct pci_dev *dev, int where, + u8 value) +{ + return pci_mmcfg_write(0, dev->bus->number, dev->devfn, + where, 1, value); +} + +static int pci_mmcfg_write_config_word(struct pci_dev *dev, int where, + u16 value) +{ + return pci_mmcfg_write(0, dev->bus->number, dev->devfn, + where, 2, value); +} + +static int pci_mmcfg_write_config_dword(struct pci_dev *dev, int where, + u32 value) +{ + return pci_mmcfg_write(0, dev->bus->number, dev->devfn, + where, 4, value); +} + +static struct pci_ops pci_mmcfg = { + pci_mmcfg_read_config_byte, + pci_mmcfg_read_config_word, + pci_mmcfg_read_config_dword, + pci_mmcfg_write_config_byte, + pci_mmcfg_write_config_word, + pci_mmcfg_write_config_dword +}; + +struct pci_ops * __devinit pci_mmcfg_init(void) +{ + if ((pci_probe & PCI_PROBE_MMCONF) == 0) + goto out; + if (!pci_mmcfg_base_addr) + goto out; + + printk(KERN_INFO "PCI: Using MMCONFIG\n"); + pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; + + return &pci_mmcfg; + +out: + return NULL; +} + +int pci_mcfg_read(int seg, int bus, int dev, int fn, int reg, int len, + u32 *value) +{ + pci_mmcfg_read(seg, bus, PCI_DEVFN(dev, fn), reg, len, value); +} + +int pci_mcfg_write(int seg, int bus, int dev, int fn, int reg, int len, + u32 *value) +{ + pci_mmcfg_write(seg, bus, PCI_DEVFN(dev, fn), reg, len, value); +} diff -urN wt1-721/arch/x86_64/kernel/pci-pc.c wt1/arch/x86_64/kernel/pci-pc.c --- wt1-721/arch/x86_64/kernel/pci-pc.c Fri Aug 13 22:13:42 2004 +++ wt1/arch/x86_64/kernel/pci-pc.c Fri Aug 13 22:14:00 2004 @@ -27,7 +27,7 @@ #include "pci-x86_64.h" -unsigned int pci_probe = PCI_PROBE_CONF1 | PCI_PROBE_CONF2; +unsigned int pci_probe = PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | PCI_PROBE_MMCONF; int pcibios_last_bus = -1; struct pci_bus *pci_root_bus; @@ -566,6 +566,31 @@ printk("??? no pci access\n"); #endif +#ifdef CONFIG_PCI_MMCONFIG + pci_root_ops = pci_mmcfg_init(); + if (pci_root_ops) { + pci_config_read = pci_mcfg_read; + pci_config_write = pci_mcfg_write; + } +#ifdef CONFIG_PCI_DIRECT + else { + /* + * PCI Express option is enabled in NON-PCI Express + * platforms. Reset the PCI root ops + */ + 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; + } + } +#endif +#endif + return; } @@ -580,6 +605,19 @@ if (pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2)) dir = pci_check_direct(); #endif + +#ifdef CONFIG_PCI_MMCONFIG + dir = pci_mmcfg_init(); +#ifdef CONFIG_PCI_DIRECT + /* + * PCI Express option is enabled in NON-PCI Express + * platforms. Reset the PCI root ops + */ + if (!dir) { + dir = pci_check_direct(); + } +#endif +#endif if (dir) pci_root_ops = dir; else { @@ -630,6 +668,12 @@ } else if (!strcmp(str, "conf2")) { pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS; + return NULL; + } +#endif +#ifdef CONFIG_PCI_MMCONFIG + else if (!strcmp(str, "nommconf")) { + pci_probe &= ~PCI_PROBE_MMCONF; return NULL; } #endif diff -urN wt1-721/arch/x86_64/kernel/pci-x86_64.h wt1/arch/x86_64/kernel/pci-x86_64.h --- wt1-721/arch/x86_64/kernel/pci-x86_64.h Fri Aug 13 22:13:42 2004 +++ wt1/arch/x86_64/kernel/pci-x86_64.h Fri Aug 13 22:14:00 2004 @@ -15,6 +15,8 @@ #define PCI_PROBE_BIOS 0x0001 #define PCI_PROBE_CONF1 0x0002 #define PCI_PROBE_CONF2 0x0004 +#define PCI_PROBE_MMCONF 0x0008 +#define PCI_PROBE_MASK 0x000f #define PCI_NO_SORT 0x0100 #define PCI_BIOS_SORT 0x0200 #define PCI_NO_CHECKS 0x0400 @@ -74,3 +76,10 @@ void pcibios_enable_irq(struct pci_dev *dev); void pci_iommu_init(void); + +/* mmconfig.c */ +int pci_mcfg_read(int seg, int bus, int dev, int fn, int reg, int len, + u32 *value); +int pci_mcfg_write(int seg, int bus, int dev, int fn, int reg, int len, + u32 *value); +struct pci_ops * __devinit pci_mmcfg_init(void); diff -urN wt1-721/drivers/acpi/Config.in wt1/drivers/acpi/Config.in --- wt1-721/drivers/acpi/Config.in Fri Aug 13 22:13:42 2004 +++ wt1/drivers/acpi/Config.in Fri Aug 13 22:14:00 2004 @@ -14,6 +14,7 @@ define_bool CONFIG_ACPI_INTERPRETER y define_bool CONFIG_ACPI_EC y define_bool CONFIG_ACPI_POWER y + define_bool CONFIG_ACPI_MMCONFIG y if [ "$CONFIG_PCI" = "y" ]; then define_bool CONFIG_ACPI_PCI y define_bool CONFIG_ACPI_MMCONFIG y @@ -73,6 +74,7 @@ define_bool CONFIG_ACPI_BUS y define_bool CONFIG_ACPI_INTERPRETER y define_bool CONFIG_ACPI_POWER y + define_bool CONFIG_ACPI_MMCONFIG y define_bool CONFIG_ACPI_SYSTEM y tristate ' Button' CONFIG_ACPI_BUTTON tristate ' Fan' CONFIG_ACPI_FAN diff -urN wt1-721/drivers/pci/pci.c wt1/drivers/pci/pci.c --- wt1-721/drivers/pci/pci.c Fri Aug 13 22:13:42 2004 +++ wt1/drivers/pci/pci.c Fri Aug 13 22:14:00 2004 @@ -36,6 +36,9 @@ #define DBG(x...) #endif +#define PCI_CFG_SPACE_SIZE 256 +#define PCI_CFG_SPACE_EXP_SIZE 4096 + LIST_HEAD(pci_root_buses); LIST_HEAD(pci_devices); @@ -165,6 +168,8 @@ * %PCI_CAP_ID_CHSWP CompactPCI HotSwap * * %PCI_CAP_ID_PCIX PCI-X + * + * %PCI_CAP_ID_EXP PCI Express */ int pci_find_capability(struct pci_dev *dev, int cap) @@ -199,6 +204,21 @@ return 0; } +/** + * pci_cfg_space_size - get the configuration space size of the PCI device. + * Regular PCI devices have 256 bytes, but PCI-X 2 and PCI Express devices + * have 4096 bytes. + */ +static int pci_cfg_space_size(struct pci_dev *dev) +{ + int pos; + + pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (pos) + return PCI_CFG_SPACE_EXP_SIZE; + + return PCI_CFG_SPACE_SIZE; +} /** * pci_find_parent_resource - return resource region of parent bus of given region @@ -1426,6 +1446,9 @@ dev->slot_name, class, dev->hdr_type); dev->class = PCI_CLASS_NOT_DEFINED; } + + /* Get the config space size */ + dev->cfg_size = pci_cfg_space_size(dev); /* We found a fine healthy device, go go go... */ return 0; diff -urN wt1-721/drivers/pci/proc.c wt1/drivers/pci/proc.c --- wt1-721/drivers/pci/proc.c Fri Aug 13 22:13:42 2004 +++ wt1/drivers/pci/proc.c Fri Aug 13 22:14:35 2004 @@ -16,12 +16,13 @@ #include #include -#define PCI_CFG_SPACE_SIZE 256 - static loff_t proc_bus_pci_lseek(struct file *file, loff_t off, int whence) { loff_t new; + const struct inode *ino = file->f_dentry->d_inode; + const struct proc_dir_entry *dp = ino->u.generic_ip; + struct pci_dev *dev = dp->data; switch (whence) { case 0: @@ -31,12 +32,12 @@ new = file->f_pos + off; break; case 2: - new = PCI_CFG_SPACE_SIZE + off; + new = dev->cfg_size + off; break; default: return -EINVAL; } - if (new < 0 || new > PCI_CFG_SPACE_SIZE) + if (new < 0 || new > dev->cfg_size) return -EINVAL; return (file->f_pos = new); } @@ -58,7 +59,7 @@ */ if (capable(CAP_SYS_ADMIN)) - size = PCI_CFG_SPACE_SIZE; + size = dev->cfg_size; else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) size = 128; else @@ -134,12 +135,12 @@ unsigned pos = n; int cnt; - if (pos != n || pos >= PCI_CFG_SPACE_SIZE) + if (pos != n || pos >= dev->cfg_size) return 0; - if (nbytes >= PCI_CFG_SPACE_SIZE) - nbytes = PCI_CFG_SPACE_SIZE; - if (pos + nbytes > PCI_CFG_SPACE_SIZE) - nbytes = PCI_CFG_SPACE_SIZE - pos; + if (nbytes >= dev->cfg_size) + nbytes = dev->cfg_size; + if (pos + nbytes > dev->cfg_size) + nbytes = dev->cfg_size - pos; cnt = nbytes; if (!access_ok(VERIFY_READ, buf, cnt)) @@ -391,7 +392,7 @@ return -ENOMEM; e->proc_fops = &proc_bus_pci_operations; e->data = dev; - e->size = PCI_CFG_SPACE_SIZE; + e->size = dev->cfg_size; return 0; } diff -urN wt1-721/include/asm-i386/fixmap.h wt1/include/asm-i386/fixmap.h --- wt1-721/include/asm-i386/fixmap.h Fri Aug 13 22:13:42 2004 +++ wt1/include/asm-i386/fixmap.h Fri Aug 13 22:14:00 2004 @@ -76,6 +76,9 @@ FIX_ACPI_BEGIN, FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1, #endif +#ifdef CONFIG_PCI_MMCONFIG + FIX_PCIE_MCFG, +#endif __end_of_permanent_fixed_addresses, /* temporary boot-time mappings, used before ioremap() is functional */ #define NR_FIX_BTMAPS 16 diff -urN wt1-721/include/asm-x86_64/fixmap.h wt1/include/asm-x86_64/fixmap.h --- wt1-721/include/asm-x86_64/fixmap.h Fri Aug 13 22:13:42 2004 +++ wt1/include/asm-x86_64/fixmap.h Fri Aug 13 22:14:00 2004 @@ -46,6 +46,9 @@ FIX_IO_APIC_BASE_0, FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1, #endif +#ifdef CONFIG_PCI_MMCONFIG + FIX_PCIE_MCFG, +#endif __end_of_fixed_addresses }; diff -urN wt1-721/include/linux/pci.h wt1/include/linux/pci.h --- wt1-721/include/linux/pci.h Fri Aug 13 22:13:42 2004 +++ wt1/include/linux/pci.h Fri Aug 13 22:14:00 2004 @@ -401,6 +401,7 @@ /* device is compatible with these IDs */ unsigned short vendor_compatible[DEVICE_COUNT_COMPATIBLE]; unsigned short device_compatible[DEVICE_COUNT_COMPATIBLE]; + int cfg_size; /* Size of configuration space */ /* * Instead of touching interrupt line and base address registers