Re: [PATCH] powerpc/PCI: compute I/O space bus-to-resource offset consistently

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Feb 27, 2012 at 8:52 PM, Benjamin Herrenschmidt
<benh@xxxxxxxxxxxxxxxxxxx> wrote:
> On Mon, 2012-02-27 at 19:50 -0700, Bjorn Helgaas wrote:
>> --- a/arch/powerpc/kernel/pci_32.c
>> +++ b/arch/powerpc/kernel/pci_32.c
>> @@ -219,9 +219,9 @@ void __devinit pcibios_setup_phb_io_space(struct
>> pci_controller *hose)
>>         struct resource *res = &hose->io_resource;
>>
>>         /* Fixup IO space offset */
>> -       io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
>> -       res->start = (res->start + io_offset) & 0xffffffffu;
>> -       res->end = (res->end + io_offset) & 0xffffffffu;
>> +       io_offset = pcibios_io_space_offset(hose);
>> +       res->start += io_offset;
>> +       res->end += io_offset;
>>  }
>
> Well, you are losing the 0xffffffff mask... so basically, what happens
> is that your offset, if negative, will be 0 extended by
> pcibios_io_space_offset() instead of sign-extended, and thus the
> resource will have crap stuff in the top 32-bit.

I don't think it will have random crap.  Here's what I think will
happen.  Assume typical 64KB I/O port spaces, PCI bus addresses in the
range 0x0-0xffff, with isa_io_base = 0x10000000.  If we compute the
offset as I did in the patch:

    (unsigned long) hose->io_base_virt - _IO_BASE

the subtraction result is 32-bits and is zero-extended to 64 bits.
Alternatively, we could do this:

    (unsigned long long) (unsigned long) hose->io_base_virt - _IO_BASE

Here the conversion to 64 bits happens before the subtraction, so the
upper 32 bits of the result are likely all ones.  Examples:

hose->io_base_virt      offset                  resource
0x10000000              0x00000000              [io 0x0000-0xffff]
0x11000000              0x01000000              [io 0x01000000-0x0100ffff]
0x0f000000              0xff000000              [io 0xff000000-0xff00ffff]

0x10000000              0x00000000              [io 0x0000-0xffff]
0x11000000              0x01000000              [io 0x01000000-0x0100ffff]
0x0f000000              0xffffffffff000000      [io
0xffffffffff000000-0xffffffffff00ffff]

Either way will probably work since you only care about the low 32
bits, which are the same either way.  I chose the first because
casting the 32-bit pointer to a 64-bit value seemed to require two
ugly casts and the resulting resource values look unwieldy when
printed.

Bjorn
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux