XHCI with USB 2.0 Mass storage device [SOLVED]

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
prajwal
Member
Member
Posts: 154
Joined: Sat Oct 23, 2004 11:00 pm
Contact:

XHCI with USB 2.0 Mass storage device [SOLVED]

Post by prajwal »

Hello,

I have started to write XHCI controller driver specifically to support USB mass storage device (the one I am using is a USB 2.0 High speed device)

I am stuck at a point where the PORTSC is not reporting any device connected and they are in disabled state (with RxDetect set to 5 --> Disconnected then ?)

On my laptop, I have XHCI controller with 8 ports

Ports 1 to 4 are USB 2.0 while Ports 5 to 8 are USB 3.0 ports (information that I read from Extended Supported Protocol Registers)

I am able to boot from my USB 2.0 pen drive (which is booting with grub UEFI - and my kernel is in ELF format)

I do the following:-
1. Identify the PCI entry for XHCI
2. Memory map the IO space
3. Load Extended Capability registers for ID 1 (LEGSUP) and ID 2 (Supported Protocol)
4. Enable Bus Master (Writing 0x6)
5. Perform BIOS to OS Handoff
6. Wait for CNR to be "0" (i.e HC Ready)
7. Do HC RESET
8. Setup MaxSlots (non zero value)
9. Set DCBAAP
10. Set Command Ring Pointer with a CD which has one Command TRB and one link TRB
11. Start HC
12. Check that HC Halted is "0" and HC Running is "1"
13. Iterate through Ports
While iterating through Ports in Operational register space (First 4 are USB 2.0 and last 4 ports are USB 3.0 ports)
- I am seeing that all 8 ports are showing "no device connected"
- PED is 0, PP is "1" with RxDetect set to "5"
- PPC bit is "0" - indicating Hardware port power control (?)
- I do a Port Reset on USB 2.0 ports. Port Reset times out (that is I don't see PRC changing from 0 to 1 in a span of 2 seconds timeout). PED is still "0" !

When I boot to Linux, I see that the USB 2.0 pen drive is shown under XHCI_HCD, 480M in lsusb -t command output -> indicating that USB 2.0 device should have been connected to one of USB 2.0 ports of XHCI controller

I have checked PCI POWER, HLC, IHI flags in Extended Supported Protocol registers - but all seems fine. PCI POWER STATUS and CONTROL register shows value of zero indicating that controller is in D0 state (fully powered state). HLC and IHI bits are all zero

I am stuck at this point and don't know why my USB 2.0 device is not shown as connected on any of the ports (including USB 2.0 ports).
I am sure I am missing some key step - Please help!

Regards,
- Prajwala
Last edited by prajwal on Sat May 21, 2016 10:30 pm, edited 1 time in total.
complexity is the core of simplicity
TomT
Member
Member
Posts: 42
Joined: Sat Mar 15, 2008 7:20 am
Location: Wisconsin, USA
Contact:

Re: XHCI with USB 2.0 Mass storage device

Post by TomT »

Does your xhci have a root hub ? Then you need hub class commands to enable ports and detect
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: XHCI with USB 2.0 Mass storage device

Post by BenLunt »

Did you reset the actual port?

Here are a few notes:
- The host controller may not apply power to a port until after a write to the MaxSlotsEnabled field in
the Config Operations Register (offset 0x38). This is so the ports will not consume power until the
driver is loaded and ready.
- Did you power the port? A reset will not happen unless the port is powered.
- Did you use bit 4 or bit 31 for the reset?
Bit 4 for USB2 and bit 31 for USB3
- If it is a USB2 device, you must deactivate the USB3 port. I.e.: set the protocol of the port to USB2.

Chapter 9, 10, and 14 in "USB: The Universal Serial Bus" (http://www.fysnet.net/the_universal_serial_bus.htm)
describes in detail, step by step how to detect and enumerate an xHCI root hub.

Ben
User avatar
prajwal
Member
Member
Posts: 154
Joined: Sat Oct 23, 2004 11:00 pm
Contact:

Re: XHCI with USB 2.0 Mass storage device

Post by prajwal »

TomT wrote:Does your xhci have a root hub ? Then you need hub class commands to enable ports and detect
Ben wrote: Did you power the port? A reset will not happen unless the port is powered.
Can you please point me to the section in Intel XHCI spec where it explains how to power the port ? or should I have to read some other spec or doc ?
Just to highlight, PPC bit is "0" and PP (Port Power) bit is "1" -> which means the Port Power switch is not off

I have tried doing PR for USE 2.0 - it doesn't help. As I mentioned in my initial post, PED is still 0 and PRC doesn't change to 1
complexity is the core of simplicity
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: XHCI with USB 2.0 Mass storage device

Post by BenLunt »

Here is a paragraph from the book:
The Port Power bit is to switch power on or off for this port. If the Port Power Control (PPC) bit in the HCCPARAMS1 register is set, the Port Power bit will turn on or off the power to this port. If the PPC bit is clear, the port is always powered. However, since different controllers will control power differently, this bit must be set to one to use the port. If this bit is zero, the port will not show a connect status, nor read any values from the port no matter the state of the PPC bit in the HCCPARAMS1 register. If your driver sets the Port Power bit to a one from a zero, you must wait a minimum of 20mS before you can use the port.
Whether the PPC bit is set or clear, you still have to set bit 9 in the PortSC register, remembering that if you change the bit to a one from a zero, you need to wait for the power to settle. After waiting the 20mS, check to see that the bit actually did get set.

Here is a snippet of code from the source:

Code: Select all

  // power the port?
  if ((xhci_read_op_reg(HCPortStatusOff + xHC_Port_PORTSC) & (1<<9)) == 0) {
    xhci_write_op_reg(HCPortStatusOff + xHC_Port_PORTSC, (1<<9));
    mdelay(20);
    if ((xhci_read_op_reg(HCPortStatusOff + xHC_Port_PORTSC) & (1<<9)) == 0)
      return FALSE;  // return bad reset.
  }
Note that if you power the port via the USB3 protocol register, the USB2 protocol register will also show the power being set, and visa-versa.
The port will not show connection or enabled until the port is powered.

Once the port is powered, you then do a reset, which will set the Enabled bit if a device is attached.

Here is a few paragraphs from page 9-24:
The port’s register set contains a Port Speed field to tell us which speed the attached device is. However, this field is invalid on the USB2 protocol port register set until after the reset, but is valid on the USB3 port register set before the reset, if a super-speed device is attached. Therefore, we must reset the port before we can use this speed field to determine which port register set to use, the USB3 port register set or the associated USB2 port register set.

Before resetting the port, the HcHalted bit in the USBSTS register must be zero. Since you cannot write a zero to this bit, you must start the schedule by setting the Run/Stop bit in the USBCMD register, assuming you have at least a valid empty schedule.

There is not much difference in resetting a USB2 protocol port than resetting a USB3 protocol port. Using bit 4 is a Hot Reset, while using bit 31 would be a Warm Reset and is only supported on USB3 protocol ports. The difference between the two is a Warm Reset, on a USB3 protocol port, will force the link hardware to enter the Rx.Detect state, indicating that the link detection should be performed again.

When resetting either protocol’s port, do a Hot Reset, setting bit 4. The port will reset, then if successful, it will set bit 21, and will show the connection status and enable the port. Once you reset the port, check to see if the connection and enabled status is set. If so, you have a device attached that corresponds to the protocol of that port. For example, if you are resetting a USB2 protocol port register set, and it is successful, you will have a USB 2.0 device attached, either a low-, full-, or high speed device. If you are resetting a USB3 protocol port register set, and it is successful, you have a super-speed device attached. Your driver cannot enable a port by writing a one to the Port Enabled/Disabled bit. The controller will only set this bit if a successful reset occurred and a device is attached.

A Hot reset can take as little as 1mS, while a Warm Reset may take a bit longer, in some cases it can take up to 250mS. You can poll bit 21 to see when the Hot Reset is complete. You must use bit 4 on all USB2 protocol port register sets, but may use either bit 4 or bit 31 on a USB3 protocol port register set. Just remember that using a Warm Reset will take longer to perform than a Hot Reset, and you must check bit 19 for a Warm Reset completion.
Hope this helps.
User avatar
prajwal
Member
Member
Posts: 154
Joined: Sat Oct 23, 2004 11:00 pm
Contact:

Re: XHCI with USB 2.0 Mass storage device

Post by prajwal »

Thanks for suggestions Ben. However, I have already tried that and I gave it a try again - but to no avail
Port Power is already = 1. To try your suggestion, I set PP = 0 waited for 100 ms and then set PP = 1 and waited for 100 ms. Asserted that PP = 1 then

To highlight few points (which is also there in my initial post):-
1. There are 8 ports
2. first 4 are USB 2.0 and last 4 are USB 3.0 ports (I checked Support Capability extended register to find USB port protocol)
3. Port Power (bit 9) PP = 1 for all 8 ports
4. The PORTSC value of first 4 (USB 2.0) ports is 0x2A0
5. The PORTSC value of last 4 (USB 3.0) ports is 0x802A0
6. I have tried setting PR = 1 for first 4 USB 2.0 ports - but the PR failed with timeout error while waiting for PRC to become "1"

I am able to start and run HC. HC Run bit is set and HC Halted is zero

Not sure what I am missing. Is there any vendor specific PCI configuration I have modify/change ? (Intel XHCI port switch/enable - not sure if it make sense just thinking if that's something I need to look into ? )
complexity is the core of simplicity
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: XHCI with USB 2.0 Mass storage device

Post by BenLunt »

When you say 8 ports, you mean 8 port register sets, yet you only have 4 actual ports, also called sockets?

Of course a value of 0x02A0 means:
Bit 9 -- Powered
Bits 8:5 -- Link State: rx.detect
Which is what you are looking for.

As for the PCI, did you make sure it was in the powered state? Within the Extended Cap registers there might be a set of power configuration registers. If not, it should be powered.

How long are you waiting for the PRC bit (bit 21) to be set?
You are resetting a USB2 port, correct?
If you are resetting a USB3 port, try bit 31 for the reset, and 19 for the change bit.

At this time, I can't think of anything else you may be doing wrong. It has been known that some manufacturers have special settings for their hardware. What is the PCI vendor ID, device ID, and rev number of your card?
User avatar
prajwal
Member
Member
Posts: 154
Joined: Sat Oct 23, 2004 11:00 pm
Contact:

Re: XHCI with USB 2.0 Mass storage device

Post by prajwal »

I have 8 port registers in operational registry space as per the value I read from HCSPARAMS1 (bits 31:24)

I have 2 Extended Supported Protocol Capability entries in PCI space. One is with Major version = 2 (USB 2.0) and port range 1 to 4. Second is with Major version = 3 (USB 3.0) and port range 5 to 8

So, I do Port Reset (by setting PR (bit 4) = 1 ) for PORTSC from 1 to 4

I see 2 additional vendor specific extended capability registers with capability ID 192 and 193. I don't see any other extended cap register for PCI power

Vendor: 0x8086
Device: 0x1E31
Revision: 4

When I boot to ubuntu, this is what I see from lspci output for XHCI controller
USB controller: Intel Corporation 7 Series/C210 Series Chipset Family USB xHCI Host Controller (rev 04) (prog-if 30 [XHCI])
complexity is the core of simplicity
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: XHCI with USB 2.0 Mass storage device

Post by BenLunt »

First of all, do me a favor. Go to http://www.fysnet.net/usb_help.htm and download the .zip file there. This .zip file contains xhci.exe which needs to be ran from a DOS environment. If you don't have a DOS environment, the .zip file also contains a 1.44meg floppy image with FreeDOS already installed, along with xhci.exe. (Hopefully you still have a floppy disk on this machine).

If you have a way to run this app, please use the -d parameter:
xhci -d > xhci.txt

This will dump a lot of information about the xhci controller to the xhci.txt file. Please send this .txt file to me. (See the readme.txt file for information on how to send it to me)

Second, we look up the specs for the C210 Series Chipset.
http://www.intel.com/content/www/us/en/ ... sheet.html

BTW, you did enable the Bus Master Enable and Memory Space Enable bits in the PCI's Command Register, yes? Bits 2 and 1.

See section 17.1.19: Is the OC bit set?
See section 17.1.21: I have this field set to 60000 (32)
See section 17.1.22: You said your adapter does not have this field. Correct?
See section 17.1.35: Enable the xHCI to allow the software to see a xHCI connection.

This chipset has two EHCI controllers. It wouldn't be that the root hub is sending all USB2.0 devices to the EHCI controllers?
I didn't read the chipset specs long enough to see what it does with USB 2.0 devices.

Hope this helps,
Ben
User avatar
prajwal
Member
Member
Posts: 154
Joined: Sat Oct 23, 2004 11:00 pm
Contact:

Re: XHCI with USB 2.0 Mass storage device

Post by prajwal »

Thanks Ben, I will give this a try once I go home from office
Ben wrote:BTW, you did enable the Bus Master Enable and Memory Space Enable bits in the PCI's Command Register, yes? Bits 2 and 1.
Yes
Ben wrote:This chipset has two EHCI controllers. It wouldn't be that the root hub is sending all USB2.0 devices to the EHCI controllers?
I can enumerate EHCI controller ports successfully and I am able to identify same set of devices that I also see in Ubuntu lspci and lsusb output

Meanwhile, I tried another thing today morning before rushing to office which I couldn't update so far

For Intel Device 0x1E31 (PantherPoint XHCI) - I found this link http://permalink.gmane.org/gmane.linux. ... ead/303467

I didn't go through the details but I saw there is a vendor specific config to enable XHCI ports. So, I just gave it a try to enable USB 3.0 and USB 2.0 ports on XHCI controller

After I did this, I see that the USB 2.0 port where my USB 2.0 pen drive is plugged-in has now got DeviceConnected bit set to "1" and I was able to do PR successfully (without timeout). However, the PED was still "0" even after PortReset. I will check this once I get back home and also read through the intel manual sections that you highlighted. I feel like I am going to resolve it this weekend :) Once again want to thank you for your help - will update soon
complexity is the core of simplicity
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: XHCI with USB 2.0 Mass storage device

Post by BenLunt »

Ah yes, the PantherPoint hardware. When I was doing my research for the book, I came across this hardware and found that it indeed does share the sockets between the EHCI and the xHCI controllers. You do have to set some configuration registers to tell the hardware which controller to use.

Give it a try and let us know what you find out. If you can't get it, I think I still have my notes on the PantherPoint and could dig them up and see what I can contribute.

Thanks,
Ben
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: XHCI with USB 2.0 Mass storage device

Post by BenLunt »

P.S. Write 0xFFFFFFFF (as a dword) to the PCI Config Registers 0xD8 and 0xD0, each. Setting all available bits in 0xD8 will switch all available xHCI sockets to the xHCI controller. A clear bit in the 0xD0 register indicates to use the EHCI controller, hence trying to set those bits.

Note that not all ports may be switchable, and it you might read it back just to see which one were.

Another note is that you should do this switch before you enumerate devices via the EHCI controller. If you enumerate the EHCI devices, then do this switch, all the devices attached will now be "dead". Therefore, in your driver if you find an EHCI controller, I would check to see if it is a Panther Point. If so, perform this switch task first.

See sections 17.1.33 and 17.1.35 of the specification I quoted earlier for more information.

Good luck,
Ben
User avatar
prajwal
Member
Member
Posts: 154
Joined: Sat Oct 23, 2004 11:00 pm
Contact:

Re: XHCI with USB 2.0 Mass storage device

Post by prajwal »

Ok, I now finally have PORTSC with DeviceConnected and PED = 1 for USB 2.0 pen drive

To summarize,

1. To being with, I was not seeing any device connected to any of my USB 2.0 ports (PORTSC bit 0 = 0)
2. After doing XHCI port switch as required by Intel PantherPoint USB controller, I was able to see device connected (PORTSC bit 0 = 1)
3. However, the Port was still in disabled state (PED = 0) even after PortReset
4. The reason why PortReset was not getting Port enabled is because for some reason (I don't know what made me do that :)), I was clearing PRC bit immediately after I asserted the value of PRC changing from 0 to 1
5. So, now to perform PortReset, I do:
a. Clear PRC (by writing PRC = 1)
b. Do PortReset (write PR = 1)
c. Wait for PRC to change from 0 to 1 (DO NOT clear PRC after this step)
d. Proceed to check if PED is set

Thanks Ben for your help!! Now, I have a lot of work to program command, transfer and event rings to complete my XHCI driver - that will certainly take some amount of time.

(I will mark this issue as SOLVED. I may encounter more issues or get stuck with other stuff before completing XHCI controller driver but that shall come as a separate topic/thread :))
complexity is the core of simplicity
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: XHCI with USB 2.0 Mass storage device [SOLVED]

Post by BenLunt »

Good to hear it. Yes, be sure to post again if you have any problems and I will do my best to help out.

Ben

http://www.fysnet.net/the_universal_serial_bus.htm
User avatar
prajwal
Member
Member
Posts: 154
Joined: Sat Oct 23, 2004 11:00 pm
Contact:

Re: XHCI with USB 2.0 Mass storage device [SOLVED]

Post by prajwal »

Hi Ben,

Just wanted to inform you that I have ordered your book "USB: The Universal Serial Bus" from Amazon.

Rather than running around multiple specs and documents back and forth multiple times, I decided to refer your book for implementing USB low level drivers for my OS upanix

I didn't know that such a book existed before and I am glad to know about it. While I am waiting for it's delivery, I have sent you a separate mail with my order confirmation details so that you can send me the iso image

Thanks for writing this book :)
complexity is the core of simplicity
Post Reply