[PATCH,RFC] PCI: deal with device incorrectly reporting I/O decoding being enabled
Matthew Wilcox
matthew at wil.cx
Sun Nov 8 11:15:42 EST 2009
On Sun, Nov 08, 2009 at 03:41:03PM +0000, Russell King - ARM Linux wrote:
> On Sun, Nov 08, 2009 at 08:23:10AM -0700, Matthew Wilcox wrote:
> > On Sun, Nov 08, 2009 at 09:04:51AM +0000, Russell King - ARM Linux wrote:
> > > Please remember that some ARM hardware only has the capability to read
> > > and write full 32-bit quantities of configuration space, which means
> > > writing the control register can result in the status register being
> > > written as well.
> > >
> > > That shouldn't be a problem, but is merely something else to consider
> > > which isn't obvious.
> >
> > Wow, that's horrid. You must have to special case each config register
> > that's accessed in a 16-bit way, since some bits are 'preserve' and others
> > are 'write 1 to clear'. What a nightmare.
>
> Yes, it's horrid, and it can be found on all IOP ARM stuff, eg:
>
> val = iop3xx_read(addr);
> if (iop3xx_pci_status())
> return PCIBIOS_SUCCESSFUL;
>
> where = (where & 3) * 8;
>
> if (size == 1)
> val &= ~(0xff << where);
> else
> val &= ~(0xffff << where);
>
> *IOP3XX_OCCDR = val | value << where;
>
> This covers IOP32x, IOP33x, and there's similar code for IOP13xx.
>
> This does mean that if we make this change, we may do more accidental
> writes to the status register on such hardware. Whether that matters
> in reality isn't something I can answer - I suspect we can get away
> with this without causing problems.
You can fix this for the status register like so:
val = iop3xx_read(addr);
if (iop3xx_pci_status())
return PCIBIOS_SUCCESSFUL;
+ /* Don't clear the RW1C bits in the Status register */
+ if (where == PCI_COMMAND)
+ val &= 0xffff;
where = (where & 3) * 8;
if (size == 1)
val &= ~(0xff << where);
else
val &= ~(0xffff << where);
*IOP3XX_OCCDR = val | value << where;
Unfortunately, this status register is not the only one with RW1C, RW1CS
or RsvdZ bits. There's the Secondary Status Register (for bridges), a
dozen PCIe Status Registers, the Dynamic Power Allocation Status Register,
the Power Management Control/Status Register ... SHPC defines a RW1C
bit in a register, not sure if we'll hit that case. I bet there's others.
I can only hope that in general, one does not find many PCI devices
attached to an IOP3xx.
--
Matthew Wilcox Intel Open Source Technology Centre
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours. We can't possibly take such
a retrograde step."
More information about the linux-arm-kernel
mailing list