Subject: OHCI question...
To: None <tech-kern@netbsd.org>
From: Garrett D'Amore <garrett_damore@tadpole.com>
List: tech-kern
Date: 10/27/2005 14:04:24
I have a device that has an "OHCI compliant" controller onboard.  It is 
directly attached rather than via PCI.

The interesting bit is that this controller always endian swaps the data 
structures in hardware to match the endianness of the host CPU (which 
can be either little or big) -- in other words undefining the htole32() 
and le32toh() macros in the OHCI driver is the only way to make the 
current code work on this processor when big-endian.  This is obviously 
bad because we might (we will!) want to have another OHCI controller on 
the PCI bus, which won't do this swapping.

Note that this swapping is performed on host memory via DMA, so an 
alternate bus_space isn't going to solve the problem.

I can think of two approaches, and I would be inerested to hear comments:

1) add logic to ohci.c to support run-time conditionalized byte 
swapping.  Probably via a function pointer in the softc, this would 
work, but might be a little bit slower.  (I'd conditionalize this 
support via a new OHCI_NATIVE_ORDER or somesuch.)

2) ultimately create a new driver, but which acts basically by 
re-#defining the few external functions to different names (e.g. 
"auhci_init", etc.), #include'ing the original ohci.c, and arranging for 
htole32/le32toh to be undefined.  (This probably also means adding a 
macro test to ohci.c, something like:

    #ifdef OHCI_NEVER_SWAP
    #undef htole32
    #undef le32toh
    #define htole32(x) (x)
    #define le32toh(x) (x)
    #endif

Its not entirely clear to me which of these approaches is preferable.  
They will both work.

Any opinions, or other suggestions?  Obviously I'd prefer to have 
something that can pass muster to be committed back to -current.

Thanks!

    -- Garrett