MPC8349ea Random Device Generator driver

Olof Johansson olof at lixom.net
Thu Jun 7 10:00:40 EST 2007


On Wed, Jun 06, 2007 at 05:48:03PM -0500, Timur Tabi wrote:
> Olof Johansson wrote:
> 
> > 	typedef __u16 __bitwise __le16;
> > 	typedef __u16 __bitwise __be16;
> > 	typedef __u32 __bitwise __le32;
> > 	typedef __u32 __bitwise __be32;
> > 	typedef __u64 __bitwise __le64;
> > 	typedef __u64 __bitwise __be64;
> 
> Wait a minute - why are all the endian-specific types __bitwise?
> 
> What if I have a 32-bit MMIO register that just contains a number, but it has to be 
> written in big-endian?  I can't use __be32 to designate it.
> 
> For instance, I was going to do this for a new memory-mapped device I'm working with:
> 
> struct ccsr_dma {
> 	u8 res0[0x100];
> 	struct {
> 		__be32 mr;	/* x00 Mode register */
> 		__be32 sr;	/* x04 Status register */
> 		__be32 eclndar; /* x08 Current link descriptor extended address register */
> 		__be32 clndar;	/* x0C Current link descriptor address register */
> 		__be32 satr;	/* x10 Source attributes register */
> 		__be32 sar;	/* x14 Source address register */
> ...
> 		u8 res2[0x38];
> 	} channel[4];
> }
> 
> The SAR register is defined as:
> 
> Bits	Name	Description
> 0?31	SAD	Source address. This register contains the low-order bits of the 36-bit source 
> address of the DMA transfer.  The contents are updated after every DMA write operation 
> unless the final stride of a striding operation is less than the stride size, in which 
> case it remains equal to the address from which the last stride began.
> 
> In other words, the SAR register is just one number, but it must be written as a single 
> big-endian number.  So is __be32 the wrong type?

It doesn't matter a whole lot what the type is, but you should only ever
read and write registers with the MMIO ops, never directly as variable
references. You should never ever dereference an __iomem pointer (which
is what you get back from ioremap and friends)[1].

If you use in_be32/out_be32() on it, you'll be fine. It will use
appropriate barriers, and it will read and write the whole word at once.

Look at it as if anything ioremap():ed is in a different address space,
and there's only a few valid ways to access that address space. Direct
derefs in code is not one of them.

If in doubt, run sparse on your code (make C=1).


-Olof

[1] there are a few, and very very few exceptions.



More information about the Linuxppc-dev mailing list