On Fri, 22 Jan 2010, Jan Andersson wrote: > > Why is this a problem? With the exception of some old code in > > ehci-au1xxx.c, this register is always read via ehci_readl(), which > > automatically takes the endianness into account. > > > > Yes, and EHCI readl() works for the other registers that are defined as > 32-bit and should be read with DWORD accesses only. However here we have > the case where CAPLENGTH is specified to be at byte offset 0 (as opposed > to a bit position within a 32-bit word). On a big endian system byte 0 > is 31:24 in a 32-bit word and on a little endian system it is 7:0 (in a > 32-bit word). > > For the big endian version of the host controller I need to set > ehci->big_endian_mmio to 1 so that the reads and writes to registers are > not byte swapped by software (I run on SPARC that is big endian). > ehci_readl will then call readl_be() that will return a 32 bit word > organized as CAPLENGTH : RESERVED : HCIVERSION. > > Since CAPLENGTH is defined to be a 8-bit register at offset base + 0x0 > this is the expected position of that register (on a big endian system) > when doing a 32-bit read access. But it does not match with the > definition of HC_LENGTH(p). > > This issue would not have come up if CAPLENGTH and HCIVERSION were > specified as members of a 32-bit register (as most of the other > registers are). If you do not agree with me think of the case where > CAPLENGTH, as specified, is read out using a byte access. The > specification says that it is located at offset 0. Should a 32-bit read > on a big endian system return CAPLENGTH on any other position that 31:24 > on a 32-bit read to offset 0 then that byte will not be located at the > specified address. So change the places that compute HC_VERSION and HC_LENGTH. Instead of doing HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)) make them do HC_VERSION(le32_to_cpu(readl(&ehci->caps->hc_capbase))); and similarly for HC_LENGTH. That'll do what you want, won't it? Apart from bus glue, these things occur only once in ehci-dbg.c and ehci-hcd.c. Include a comment explaining that ehci_readl() can't be used here because the register is defined in terms of byte offsets rather than as a 32-bit word. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html