Re: EHCI: Definitions of HC_LENGTH and HC_VERSION

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 22 Jan 2010, Jan Andersson wrote:

> Hi,
> 
> I am writing bus glue to add support for a USB host controller that, 
> depending on the implementation, may have big or little endian registers 
> (and descriptors). Everything is working fine when running on a system 
> that has the controller in little endian mode. However, when running 
> with a big endian host controller I get into problems with the following 
> definitions in include/linux/usb/ehci-def.h:
> 
> #define HC_LENGTH(p)		(((p)>>00)&0x00ff)	/* bits 7:0 */
> #define HC_VERSION(p)		(((p)>>16)&0xffff)	/* bits 31:16 */
> 
> The EHCI specification defines CAPLENGTH as an 8-bit register at offset 
> 0. The byte at offset 0x01 is reserved and HCIVERSION is a 2 byte 
> register at offset 0x02. Since the macros above are used on a word they 
> make sense for little endian. However, in a big endian system a 32-bit 
> read would return the registers in the following order:
> 
> CAPLENGTH : RESERVED : HCIVERSION
> 
> as opposed to the little endian arrangement of:
> 
> HCIVERSION : RESERVED : CAPLENGTH
> 
> On a big endian system this means that HC_LENGTH will select the LSB of 
> HCIVERSION and HC_VERSION will select CAPLENGTH plus the reserved field. 
>   Since there is support for other big endian host controllers I assume 
> that they have considered HCIVERSION and CAPLENGTH to not be individual 
> registers and instead that they are part of a 32-bit register. This 
> works fine since the capability registers are always read using a 32-bit 
> read.
> 
> I would like to fix this so that a host controller that is (truly) big 
> endian can be used. The best way would have been to access CAPLENGTH and 
> HCIVERSION using byte and half-word accesses. But according to the 
> comment in ehci-def.h this is bad since some hosts can't perform these 
> types of accesses and it would also break for current "big" endian host 
> controllers.
> 
> The only decent way of fixing this, that I can come up with, is to let 
> the initialization code read out the two values and store them in struct 
> ehci_hcd. Would this be an acceptable solution?

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.

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

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux