The OHCI spec has defined the hcca as mixed u32 and u16.
[usb-ohci.h]
struct ohci_hcca {
__u32 int_table[NUM_INTS]; /* Interrupt ED table */
__u16 frame_no; /* current frame number */
__u16 pad1; /* set to 0 on each frame_no change */
__u32 done_head; /* info returned for an interrupt */
u8 reserved_for_hc[116];
} __attribute((aligned(256)));
linux correctly does cpu_to_le16 and vice-versa conversions to convert to little
endian for the frame_no field.
However, it appears that the MIPs processor does 32 bit bus writes, which means that
the frame_no and pad1 fields are swapped when written to the fpga/usb controller.
The correct way for Intel to have done this, in my opinion, is to define all hardware
descriptor elements as u32, to work with a larger number of embedded processors, and
to simplify fpga design between the host and the usb controller. As a result, it is
necessary to have special fpga bits to define where the frame_no ended up, and options
to correct any byte swap issues. This could have been avoided with a consistent u32
interface throughout, and a generic 32-bit endian-swap.
A software workaround would be to concatenate the frame_no and pad1 together, and use
macros to access the frame_no from the u32 field, as per the technique below.
Feedback?
Darwin Rambo
Broadcom Corp.
> -----Original Message-----
> From: Darwin Rambo
> Sent: Monday, October 20, 2003 11:40 AM
> To: '[EMAIL PROTECTED]'
> Subject: Patch to 2.4.23-pre7 for USB2.0 on big endian machines
>
> Here are fixes for a couple of different big endian problems that showed up on one
> of our MIPS32 board which prevented USB 2.0 from working big endian. Without these
> patches, I don't think USB2.0 could have worked on any big endian architecture,
> unless the length and hci_version were by coincidence the same values after
> swapping...
>
> The 2nd patch (0x7F mask) has already been fixed in 2.6.0-test8, according to David
> B.
>
> Basically, these 3 fields are organized little endian in ehci.h, rather than as a
> u32. This caused the version and length fields to be swapped and misinterpreted. The
> offset to the registers became bad, causing seg faults.
> u8 length; /* CAPLENGTH - size of this struct */
> u8 reserved; /* offset 0x1 */
> u16 hci_version; /* HCIVERSION - offset 0x2 */
>
> The other problem is that
> if (le32_to_cpu (qh->hw_info1 & 0x7f) == 0)
> should be
> if ((le32_to_cpu (qh->hw_info1) & 0x7f) == 0)
> i.e. the le32_to_cpu conversion must be done on the hw_info1 before the & 0x7f or
> the address in subsequent transactions will be incorrect and the device won't
> respond correctly.
>
> Please let me know if you need anything else.
>
> (This is my first submission, so I probably messed something up...I'm sure you'll
> let me know?)
>
> Regards,
>
> Darwin Rambo,
> Broadcom Corporation
>
>
> << File: patch.linux.2.4.23-pre7-usb2.0fixes >>
>
-------------------------------------------------------
This SF.net email is sponsored by: The SF.net Donation Program.
Do you like what SourceForge.net is doing for the Open
Source Community? Make a contribution, and help us add new
features and functionality. Click here: http://sourceforge.net/donate/
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel