[SOLVED]Cannot detect connections of USB devices

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.
Post Reply
User avatar
tokusan
Member
Member
Posts: 29
Joined: Mon Feb 24, 2020 10:18 pm
Location: Japan

[SOLVED]Cannot detect connections of USB devices

Post by tokusan »

Hello. After solving a problem (viewtopic.php?f=1&t=37366), I confirmed that the event ring and the command ring of xHC worked (at least on QEMU) by sending a No-op TRB after running xHC. However, this OS cannot detect the connections of USB devices. Reading CCS bit of all port_sc registers returns 0.

I use this command to run QEMU:

Code: Select all

qemu-system-x86_64 -drive if=pflash,format=raw,file=OVMF_CODE.fd,readonly=on -drive if=pflash,format=raw,file=OVMF_VARS.fd,readonly=on -drive format=raw,file=build/ramen_os.img -no-reboot -m 4G -d int -device isa-debug-exit,iobase=0xf4,iosize=0x04 -device qemu-xhci,id=xhci -device usb-tablet,bus=xhci.0 --trace events=trace.event -no-shutdown -monitor stdio
Code: https://github.com/toku-sa-n/ramen/tree/check_each_port xHCI codes are in kernel/src/device/pci/xhci/
Trace log: https://gist.github.com/0d088d581a61c74 ... 6dc66dbecd

Am I missing something?

Thanks,

(Note that I don't enable interruptions from xHC. I just poll the event ring.)

EDIT: I confirmed that the port 0 is in RxDetect state and the state didn't change. According to Ben's book, this indicates that the device has a fault (or broken?). However, my mouse device is not broken, and even if I specify `-device usb-mouse`, the state doesn't change.
Last edited by tokusan on Fri Nov 06, 2020 7:41 pm, edited 1 time in total.
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: Cannot detect connections of USB devices

Post by BenLunt »

tokusan wrote:Hello. After solving a problem (viewtopic.php?f=1&t=37366), I confirmed that the event ring and the command ring of xHC worked (at least on QEMU) by sending a No-op TRB after running xHC. However, this OS cannot detect the connections of USB devices. Reading CCS bit of all port_sc registers returns 0.

I use this command to run QEMU:

Code: Select all

qemu-system-x86_64 -drive if=pflash,format=raw,file=OVMF_CODE.fd,readonly=on -drive if=pflash,format=raw,file=OVMF_VARS.fd,readonly=on -drive format=raw,file=build/ramen_os.img -no-reboot -m 4G -d int -device isa-debug-exit,iobase=0xf4,iosize=0x04 -device qemu-xhci,id=xhci -device usb-tablet,bus=xhci.0 --trace events=trace.event -no-shutdown -monitor stdio
Code: https://github.com/toku-sa-n/ramen/tree/check_each_port xHCI codes are in kernel/src/device/pci/xhci/
Trace log: https://gist.github.com/0d088d581a61c74 ... 6dc66dbecd

Am I missing something?

Thanks,

(Note that I don't enable interruptions from xHC. I just poll the event ring.)

EDIT: I confirmed that the port 0 is in RxDetect state and the state didn't change. According to Ben's book, this indicates that the device has a fault (or broken?). However, my mouse device is not broken, and even if I specify `-device usb-mouse`, the state doesn't change.
Hi,

First, have you powered the port. Bit 0 (CCS) will be zero no matter the connection status if there is no power to the port.

Next, since QEMU is an emulator, the device is either connected or it is not. One or the other. There shouldn't be any RxDetect state.

Are you reading the registers as DWORDs and DWORDs only? i.e.: you cannot read them as BYTEs or WORDs. Even if your code is written to read as DWORDs, you need to make sure the compiler is not optimizing the read to a BYTE or WORD. QEMU will not return a valid value if you do not read as a DWORD.

Ben
User avatar
tokusan
Member
Member
Posts: 29
Joined: Mon Feb 24, 2020 10:18 pm
Location: Japan

Re: Cannot detect connections of USB devices

Post by tokusan »

BenLunt wrote:
tokusan wrote:Hello. After solving a problem (viewtopic.php?f=1&t=37366), I confirmed that the event ring and the command ring of xHC worked (at least on QEMU) by sending a No-op TRB after running xHC. However, this OS cannot detect the connections of USB devices. Reading CCS bit of all port_sc registers returns 0.

I use this command to run QEMU:

Code: Select all

qemu-system-x86_64 -drive if=pflash,format=raw,file=OVMF_CODE.fd,readonly=on -drive if=pflash,format=raw,file=OVMF_VARS.fd,readonly=on -drive format=raw,file=build/ramen_os.img -no-reboot -m 4G -d int -device isa-debug-exit,iobase=0xf4,iosize=0x04 -device qemu-xhci,id=xhci -device usb-tablet,bus=xhci.0 --trace events=trace.event -no-shutdown -monitor stdio
Code: https://github.com/toku-sa-n/ramen/tree/check_each_port xHCI codes are in kernel/src/device/pci/xhci/
Trace log: https://gist.github.com/0d088d581a61c74 ... 6dc66dbecd

Am I missing something?

Thanks,

(Note that I don't enable interruptions from xHC. I just poll the event ring.)

EDIT: I confirmed that the port 0 is in RxDetect state and the state didn't change. According to Ben's book, this indicates that the device has a fault (or broken?). However, my mouse device is not broken, and even if I specify `-device usb-mouse`, the state doesn't change.
Hi,

First, have you powered the port. Bit 0 (CCS) will be zero no matter the connection status if there is no power to the port.

Next, since QEMU is an emulator, the device is either connected or it is not. One or the other. There shouldn't be any RxDetect state.

Are you reading the registers as DWORDs and DWORDs only? i.e.: you cannot read them as BYTEs or WORDs. Even if your code is written to read as DWORDs, you need to make sure the compiler is not optimizing the read to a BYTE or WORD. QEMU will not return a valid value if you do not read as a DWORD.

Ben
Thank you for your reply.

I checked that all ports are powered. Reading the port power bits of all ports returns 1.

I found that the problem was that I didn't access to PORTSC registers as DWORD. Instead of accessing via bitfields, I tried just (port_sc & 1) then it returned 1 from port 5 and 0 from the other.
Now I'm confusing because not port 1 but port 5 returns 1. QEMU says:

Code: Select all

(qemu) info usb
  Device 0.1, Port 1, Speed 480 Mb/s, Product QEMU USB Mouse
Why?

Also QEMU says:

Code: Select all

[email protected]:usb_xhci_port_read port 1, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 2, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 3, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 4, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 5, off 0x0000, ret 0x00020ee1
[email protected]:usb_xhci_port_read port 6, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 7, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 8, off 0x0000, ret 0x000202a0
(I didn't get these outputs when I accessed via bitfields.)
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: Cannot detect connections of USB devices

Post by BenLunt »

tokusan wrote:I found that the problem was that I didn't access to PORTSC registers as DWORD.
All Operational Registers, QEMU or other, must be accessed via DWORD reads and writes.
All Capability Registers, on QEMU, must be DWORD accessed. However, on real hardware, they can be BYTE or WORD accessed.
tokusan wrote:Now I'm confusing because not port 1 but port 5 returns 1. QEMU says:

Code: Select all

(qemu) info usb
  Device 0.1, Port 1, Speed 480 Mb/s, Product QEMU USB Mouse
Why?

Also QEMU says:

Code: Select all

[email protected]:usb_xhci_port_read port 1, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 2, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 3, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 4, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 5, off 0x0000, ret 0x00020ee1
[email protected]:usb_xhci_port_read port 6, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 7, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 8, off 0x0000, ret 0x000202a0
(I didn't get these outputs when I accessed via bitfields.)
In my book, read Chapter 9, "Port Routing and Control" and look at Figure 9-1.

xHCI has a register set for the USB3 port *and* a register set for the USB2 port of a single socket.

i.e.: If a socket supports both USB 2 *and* USB 3, it will have two register sets.

QEMU, by default, supports four sockets, giving eight register sets. Four for the USB 3 and four for the USB 2. The first four are the USB 3 and the second four are the USB 2.

In the figure you show above, Port 5 is the first USB 2 register set.

If your keyboard (which is a USB 2 device) is plugged into the first socket, it will use the first USB 2 register set.

You have to parse the capabilities to find out where the Register sets are located. A controller can have the register sets any way it wants.

For example, QEMU has it as (if memory serves):
USB 3 - Socket 0
USB 3 - Socket 1
USB 3 - Socket 2
USB 3 - Socket 3
USB 2 - Socket 0
USB 2 - Socket 1
USB 2 - Socket 2
USB 2 - Socket 3

However, real hardware could have it as:
USB 2 - Socket 0
USB 2 - Socket 1
USB 2 - Socket 2
USB 2 - Socket 3
USB 3 - Socket 0
USB 3 - Socket 1
USB 3 - Socket 2
USB 3 - Socket 3

Or even:
USB 3 - Socket 0
USB 2 - Socket 0
USB 3 - Socket 1
USB 2 - Socket 1
USB 3 - Socket 2
USB 2 - Socket 2
USB 3 - Socket 3
USB 2 - Socket 3

You have to parse the controllers capabilities to find out.

Ben
- http://www.fysnet.net/the_universal_serial_bus.htm
User avatar
tokusan
Member
Member
Posts: 29
Joined: Mon Feb 24, 2020 10:18 pm
Location: Japan

Re: Cannot detect connections of USB devices

Post by tokusan »

Thank you for your reply. Now I fully understand. Thanks!

P.S.
BenLunt wrote:In my book, read Chapter 9, "Port Routing and Control" and look at Figure 9-1.
Figure 9-2?
Post Reply