USB EHCI memory mapped I/O how to use

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: USB EHCI memory mapped I/O how to use

Post by BenLunt »

I don't think your problem is with power management. Since you did not find the power management ID in the PCI config space, most likely the device is powered as far as the PCI is concerned. Therefore, you must use the xHCI controller registers to power the card. Section 4.23 in the xHCI 1.1 specification describes the power management of the card.

Again, I don't think power management is your problem. I think it must be somewhere else.

If you are reading the Config register and it is not returning what you think it should, check everything that has anything to do with reading from memory.
For example, do you have a limit less than the controllers address in your data selector register? If you are trying to read from 0xFFE00000 and your protection limit is 0xE0000000, you won't read from the controller.

Did you check to see if you are reading bytes or dwords? This was something that stung me a while back. I was reading a dword, so I thought, as the compiler optimized it to a byte read. The actual read from the controller was now a byte read and I was getting garbage. You need to make sure the compiler is not optimizing the read. The easiest way to do this is to make the memory read an external function of your C code.

Here is an example of what I was doing.

Code: Select all

if ((op_regs->HcRevision & 0x000000FF) != 0x10) return FALSE;
Even though the HcRevision member of op_regs was declared as a 32-bit dword *and* volatile, the compiler still optimized it to a byte read to get rid of the masking of the high order bytes. To keep this from happening, I included an external function similar to:

Code: Select all

bit32u mem_read_io_regs(const bit32u base, const bit32u offset) {
  volatile bit32u dword = *((bit32u *) (base + offset));
  return dword;
}
Again, please look at different aspects of your code. I really don't think it is the power management.

Ben
Post Reply