Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=11fbb00c67e19737757e747ec7dd3ba8d584f5d1
Commit:     11fbb00c67e19737757e747ec7dd3ba8d584f5d1
Parent:     0bd15c4b503b971024a3962b6a6b34c1af0628bf
Author:     Paul Mackerras <[EMAIL PROTECTED]>
AuthorDate: Mon May 7 15:16:23 2007 +1000
Committer:  Paul Mackerras <[EMAIL PROTECTED]>
CommitDate: Tue May 8 11:54:19 2007 +1000

    [POWERPC] Cope with PCI host bridge I/O window not starting at 0
    
    Currently our code to set up the data structures for a PCI host bridge
    and create the mapping for its I/O window assumes that the window
    starts at I/O port 0 on the PCI side.  If this is not true, we can end
    up with I/O port numbers in the resources for PCI devices which will
    cause an oops if a driver tries to access them via inb/outb etc.,
    because there is no mapping for the corresponding addresses.
    
    Normally the I/O window starts at 0, but there are some situations on
    partitioned machines with a hypervisor where the window may not start
    at 0.
    
    This fixes the problem by allocating space for the range from 0 to the
    end of the I/O window.  That is, hose->io_base_virt contains the
    virtual address for I/O port 0 on the PCI bus, and thus the assumption
    that hose->io_base_virt - pci_io_base is the offset between the
    "global" I/O port numbers (those in the PCI device resources) and the
    I/O port numbers on the PCI bus is maintained.
    
    For PCI host bridges that are present at boot, we only map the portion
    of that range that correspond to the bridge's I/O window.  For bridges
    added after boot we ioremap the range from 0 to the end of the I/O
    window, for now; in fact hot-added bridges should be using
    reserve_phb_iospace() and __ioremap_explicit (so they get sensible
    global port numbers), but we don't have the infrastructure yet to do
    that (basically a free_phb_iospace() routine plus appropriate
    locking).
    
    Interestingly, this makes the two arms of the if statement in
    get_bus_io_range do almost exactly the same thing; that function could
    now be simplified in a further patch.
    
    Signed-off-by: Paul Mackerras <[EMAIL PROTECTED]>
---
 arch/powerpc/kernel/pci_64.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 60d7d4b..706b7f3 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -1006,8 +1006,9 @@ void __devinit pci_process_bridge_OF_ranges(struct 
pci_controller *hose,
 
                switch ((pci_space >> 24) & 0x3) {
                case 1:         /* I/O space */
-                       hose->io_base_phys = cpu_phys_addr;
-                       hose->pci_io_size = size;
+                       hose->io_base_phys = cpu_phys_addr - pci_addr;
+                       /* handle from 0 to top of I/O window */
+                       hose->pci_io_size = pci_addr + size;
 
                        res = &hose->io_resource;
                        res->flags = IORESOURCE_IO;
@@ -1117,8 +1118,8 @@ static int get_bus_io_range(struct pci_bus *bus, unsigned 
long *start_phys,
        } else {
                /* Root Bus */
                res = &hose->io_resource;
-               *start_phys = hose->io_base_phys;
-               *start_virt = (unsigned long) hose->io_base_virt;
+               *start_phys = hose->io_base_phys + res->start;
+               *start_virt = (unsigned long) hose->io_base_virt + res->start;
                if (res->end > res->start)
                        *size = res->end - res->start + 1;
                else {
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to