1. Have you tried this patch on 32-bit SMP Sibyte with
CONFIG_SIBYTE_DMA_PAGEOPS turned on. I tried it out with 2.6.11-rc1 and
the kernel crashes on bootup when doing a clear_page. The following code
in arch/mips/mm/pg-sb1.c:

M_DM_DSCR_BASE_INTERRUPT))))
in clear_page seems to be causing a problem. I need to investigate more

2. Secondly, the Sibyte MAC driver drivers/net/sb1250-mac.c still uses
__raw_readq and __raw_writeq calls. Those will also need to be converted
to bus_* calls

Thanks
Manish Lachwani
Maciej W. Rozycki wrote:

Hello,

While trying using an IDE interface driver with big-endian systems, I've
noticed some of our port/mm I/O accessory functions/macros get endianness
incorrectly. In particular a lot of drivers expect single I/O accesses to
return correct numerical value of data as seen by the CPU while string I/O
accesses to preserve byte ordering in memory.

As the whole file seemed a bit messy to me I decided to rewrite these
functions/macros completely. To ease long-term maintenance I created
common templates for all classes of accesses which expand to appropriate
code for different transfer unit width. I made all operations to be
expressed as inline functions to catch dangerous/incorrect uses. The
result are the following function classes:

1. in*()/out*()/read*()/write*() perform single operations on data using
little-endian ordering.

2. __raw_in*()/__raw_out*()/__raw_read*()/__raw_write*() perform single
operations on data using memory ordering.

3. bus_read*()/bus_write*() perform single on data using CPU bus ordering
(that is as it appears at the bus, regardless of any address or lane
swappers that may modify it on the way between the CPU and a device).

4. __bus_readq()/__bus_writeq() are hacks for 64-bit accesses avoiding
interrupt masking when used with a 32-bit kernel and are otherwise the
same as bus_readq()/bus_writeq().

5. ins*()/outs*()/reads*()/writes*() perform string operations on data
using memory ordering yielding the same result as a corresponding DMA
transfer would.

The naming of 1., 2. and perhaps 5. above is a bit unfortunate, but that's
what much code elsewhere expects. These variants assume a ISA/EISA/PCI
bus, little-endian. They perform minimum of swapping required -- they
avoid swapping data back and forth to keep good performance. For
buses/devices that follow CPU endianness use 3. or perhaps 4. if
interrupts have already been masked.

The changes have been verified with a Malta board for port I/O and with a
SWARM one for memory-mapped I/O (with an updated driver; to be sent
separately). Broadcom SiByte systems are the only ones utilizing current
__raw_*() and ____raw_*() calls. I have a patch to convert them to
bus_*() and __bus_*() ones as appropriate ready as well.