Re: [PATCH] add delay between port write and port read

From: Arnd Bergmann (arnd@xxxxxxxx)
Date: Fri Mar 01 2019 - 16:52:44 EST

On Fri, Mar 1, 2019 at 8:19 PM Linus Torvalds
<torvalds@xxxxxxxxxxxxxxxxxxxx> wrote:
> On Fri, Mar 1, 2019 at 11:13 AM Maciej W. Rozycki <macro@xxxxxxxxxxxxxx> wrote:
> >
> > What do we do WRT straight-through vs byte-swapping properties of these
> > accessors?
> I think the whole point of __raw_xyz() is that it's the lowest level
> model. It gives you relaxed ordering (together with the ioremap
> model), and it gives you straight-through behavior.
> And yes, any driver using them needs to be aware of the byte ordering,
> which may or may not be the same as regular memory, and may or may not
> be the same as other devices.
> So __raw_xyz() is very much for low-level drivers that know what they
> are doing. Caveat user.
> "If it breaks, you get to keep both pieces"

I agree in principle, but I think we already have a lot of precedence
for __raw_xyz() being relied on having a specific behavior in
architecture independent drivers, and I think it makes sense for
architectures to provide that.

Specifically, I think we need __raw_xyz() to do the same as xyz()
on all little-endian kernels regarding byte ordering (not barriers), and
I would expect it to provide the same ordering and addressing
as swabX(xyz()) on big-endian kernels.

Without that, using __raw_xyz() to copy between RAM and
buffers in PCI memory space is broken, as you said, but the
assumption would be broken on certain older machines that
do a hardware endian swap by swizzling the address lines rather
than swapping bytes on the data bus.

The best idea I have for working around this is to never rely
on __raw_xyz() to not do byte swapping in platform specific
drivers with CPU-endian MMIO space, but to have a platform
specific set of wrappers around the normal I/O functions, and
make __raw_xyz() just do whatever we expect them to do on
PCI devices.