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

Reply via email to