QEMU's xHCI doesn't generate port status change on startup

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
8infy
Member
Member
Posts: 185
Joined: Sun Apr 05, 2020 1:01 pm

QEMU's xHCI doesn't generate port status change on startup

Post by 8infy »

Hi, I'm currently working on an xHCI driver and I'm having a problem with QEMU.

It just doesn't generate a port status change event at startup, even though it does set the port's CCS to 1.
If I hotplug a device later via device_add usb-mouse it does generate the event.

My xHCI initialization is very standard too, I follow the specification 1 for 1.
So far I tested on VMWare and 2 real laptops and they all generate the respective events at startup.
I don't want to make workarounds for QEMU specifically, and my current driver logic is completely event based. (I don't randomly poll bits and wait, etc.)

Has anyone else faced this problem and were you able to find a workaround that makes QEMU generate those events?

Thanks! :)
User avatar
BenLunt
Member
Member
Posts: 935
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: QEMU's xHCI doesn't generate port status change on start

Post by BenLunt »

Hi,

Sorry for the late reply, I have been busy with other things.

My version of QEMU does show a connection status at boot time. I think I am using version 6.0.x or something like that.

However, there are a few things you need to consider about the Connect Status bit. [It has been almost a year since I have done anything with this, so this is from memory. i.e.: I could be missing something :-) ]
1) You should not (in most cases) trust the Connect Status bit until after a reset of the port.
2) You should "enumerate" the ports to see which register sets are paired, if any.
3) You should not reset a port while the HcHalted bit is set. This means you need a working schedule and have started the controller.
4) You should reset a USB 3.0 register set before you reset its paired USB 2.0 register set (if needed).
5) If you have reset the controller, USB 3.0 ports will have been reset and if a device is attached, will already be enabled. No need to do it again. USB 2.0 ports might not do this, key term is 'might'. (A USB 1.x device is attached)

Again, this is all from memory.

Hope this helps,

Ben
- http://www.fysnet.net/the_universal_serial_bus.htm
8infy
Member
Member
Posts: 185
Joined: Sun Apr 05, 2020 1:01 pm

Re: QEMU's xHCI doesn't generate port status change on start

Post by 8infy »

BenLunt wrote:Hi,

Sorry for the late reply, I have been busy with other things.

My version of QEMU does show a connection status at boot time. I think I am using version 6.0.x or something like that.

However, there are a few things you need to consider about the Connect Status bit. [It has been almost a year since I have done anything with this, so this is from memory. i.e.: I could be missing something :-) ]
1) You should not (in most cases) trust the Connect Status bit until after a reset of the port.
2) You should "enumerate" the ports to see which register sets are paired, if any.
3) You should not reset a port while the HcHalted bit is set. This means you need a working schedule and have started the controller.
4) You should reset a USB 3.0 register set before you reset its paired USB 2.0 register set (if needed).
5) If you have reset the controller, USB 3.0 ports will have been reset and if a device is attached, will already be enabled. No need to do it again. USB 2.0 ports might not do this, key term is 'might'. (A USB 1.x device is attached)

Again, this is all from memory.

Hope this helps,

Ben
- http://www.fysnet.net/the_universal_serial_bus.htm
Hi, thanks for your reply!

Connection status bit is not really a problem here. It does set it correctly. The problem is that QEMU doesn't generate the respective "event" in the ring, when all real hardware/vmware does. When CCS goes from 0 to 1 after reset it should be setting CSC and generating the port status change event so that the driver can react to the new connection without having to manually iterate ports.
User avatar
BenLunt
Member
Member
Posts: 935
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: QEMU's xHCI doesn't generate port status change on start

Post by BenLunt »

8infy wrote: Hi, thanks for your reply!

Connection status bit is not really a problem here. It does set it correctly. The problem is that QEMU doesn't generate the respective "event" in the ring, when all real hardware/vmware does. When CCS goes from 0 to 1 after reset it should be setting CSC and generating the port status change event so that the driver can react to the new connection without having to manually iterate ports.
Oh, I see what you are saying. If I get a chance, I will look at the QEMU code and if this is the case, submit a feature request.

Thanks,
Ben
8infy
Member
Member
Posts: 185
Joined: Sun Apr 05, 2020 1:01 pm

Re: QEMU's xHCI doesn't generate port status change on start

Post by 8infy »

BenLunt wrote:
8infy wrote: Hi, thanks for your reply!

Connection status bit is not really a problem here. It does set it correctly. The problem is that QEMU doesn't generate the respective "event" in the ring, when all real hardware/vmware does. When CCS goes from 0 to 1 after reset it should be setting CSC and generating the port status change event so that the driver can react to the new connection without having to manually iterate ports.
Oh, I see what you are saying. If I get a chance, I will look at the QEMU code and if this is the case, submit a feature request.

Thanks,
Ben
Thank you! :)
Klakap
Member
Member
Posts: 297
Joined: Sat Mar 10, 2018 10:16 am

Re: QEMU's xHCI doesn't generate port status change on start

Post by Klakap »

I am not done with xHCI yet, but on other controllers I reset and initalize every connected device, no matter on connection status change bit. Maybe this can work for you(and probably later for me too), during starting of your OS one time initalize every device, no matter on event. Just an idea.
User avatar
BenLunt
Member
Member
Posts: 935
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: QEMU's xHCI doesn't generate port status change on start

Post by BenLunt »

BenLunt wrote:
8infy wrote: Hi, thanks for your reply!

Connection status bit is not really a problem here. It does set it correctly. The problem is that QEMU doesn't generate the respective "event" in the ring, when all real hardware/vmware does. When CCS goes from 0 to 1 after reset it should be setting CSC and generating the port status change event so that the driver can react to the new connection without having to manually iterate ports.
Oh, I see what you are saying. If I get a chance, I will look at the QEMU code and if this is the case, submit a feature request.

Thanks,
Ben
Hi and sorry for the long delay.

I ran a few tests and QEMU does indeed issue a Port Status Change Event when a device is connected at startup.

Code: Select all

131895252318: XHCI: irq fired
131895252318: XHCI: ED = 0, Type 34, Status 0x00000001
131895252318: XHCI: Port Status Change Event
131895252318: XHCI: USB_IRQ_DONE
Have you been able to progress on this?

Ben
8infy
Member
Member
Posts: 185
Joined: Sun Apr 05, 2020 1:01 pm

Re: QEMU's xHCI doesn't generate port status change on start

Post by 8infy »

BenLunt wrote:
BenLunt wrote:
8infy wrote: Hi, thanks for your reply!

Connection status bit is not really a problem here. It does set it correctly. The problem is that QEMU doesn't generate the respective "event" in the ring, when all real hardware/vmware does. When CCS goes from 0 to 1 after reset it should be setting CSC and generating the port status change event so that the driver can react to the new connection without having to manually iterate ports.
Oh, I see what you are saying. If I get a chance, I will look at the QEMU code and if this is the case, submit a feature request.

Thanks,
Ben
Hi and sorry for the long delay.

I ran a few tests and QEMU does indeed issue a Port Status Change Event when a device is connected at startup.

Code: Select all

131895252318: XHCI: irq fired
131895252318: XHCI: ED = 0, Type 34, Status 0x00000001
131895252318: XHCI: Port Status Change Event
131895252318: XHCI: USB_IRQ_DONE
Have you been able to progress on this?

Ben
Hi! No problem.

I haven't looked into it any further.
May I ask if you interact with the port in any way or does it issue status change right after HCI reset
and interrupter/schedule enable?

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

Re: QEMU's xHCI doesn't generate port status change on start

Post by BenLunt »

8infy wrote:Hi! No problem.
I haven't looked into it any further.
May I ask if you interact with the port in any way or does it issue status change right after HCI reset
and interrupter/schedule enable?
Thanks
Here is was happens in my driver from time of initialize (unmasking the interrupt) and the Port Change Event:

Code: Select all

131904021959: XHCI: Unmasking IRQ 22
131904021969: XHCI: irq fired
131904021969: XHCI: ED = 0, Type 48, Status 0x00000001
 Found NEC/Renesas firmware version: 30.25
131904021969: XHCI: USB_IRQ_DONE
131904021969: XHCI: irq fired
131904021969: XHCI: USB_IRQ_DONE
 NEC verification via vendor specific command NEC_TRB_TYPE_GET_UN: 131904021971: XHCI: NEC Verification
131904021971: XHCI: irq fired
131904021971: XHCI: ED = 0, Type 48, Status 0x00000001
131904021971: XHCI: USB_IRQ_DONE
131904021971: XHCI: irq fired
131904021971: XHCI: USB_IRQ_DONE
TRUE
131904021971: XHCI: irq fired
131904021971: XHCI: ED = 0, Type 33, Status 0x00000001
131904021971: XHCI: Command Completion Event
131904021971: XHCI: Command 21 Completion: 0x01000000
131904021971: XHCI: USB_IRQ_DONE
131904021971: XHCI: irq fired
131904021971: XHCI: USB_IRQ_DONE
131904021974: XHCI: irq fired
131904021974: XHCI: ED = 0, Type 33, Status 0x00000001
131904021974: XHCI: Command Completion Event
131904021974: XHCI: Command 21 Completion: 0x01000000
131904021974: XHCI: USB_IRQ_DONE
131904021974: XHCI: irq fired
131904021974: XHCI: USB_IRQ_DONE
131904021974: XHCI: irq fired
131904021974: XHCI: ED = 0, Type 33, Status 0x00000001
131904021974: XHCI: Command Completion Event
131904021974: XHCI: Command 21 Completion: 0x01000000
131904021974: XHCI: USB_IRQ_DONE
131904021974: XHCI: irq fired
131904021974: XHCI: USB_IRQ_DONE
131904021976: XHCI: irq fired
131904021976: XHCI: ED = 0, Type 33, Status 0x00000001
131904021976: XHCI: Command Completion Event
131904021976: XHCI: Command 21 Completion: 0x01000000
131904021976: XHCI: USB_IRQ_DONE
131904021976: XHCI: irq fired
131904021976: XHCI: USB_IRQ_DONE
131904021977: XHCI: irq fired
131904021977: XHCI: ED = 0, Type 34, Status 0x00000001
131904021977: XHCI: Port Status Change Event
131904021977: XHCI: USB_IRQ_DONE
However, please note that I check for the NEC card and get its version, as well as the bandwidth command, before the Port Status Change Event takes place.

...

After looking over my code some more, at the point that QEMU fires the Port Status Change Event might be where I start to enumerate the attached devices, which means I reset a port. If this is the case, then the Event might be because of the port reset.

I haven't looked into it very far. Something I will need to look into I guess. There is a possibility that QEMU isn't firing the Event as you stated before.

...

Yep, you are correct. I commented out the code that creates the root hub device, which is the driver that enumerates the attached devices. The code still resets the controller.

QEMU is not firing the Port Status Change Event after the controller reset.

I tried my code in DEBUG mode on an actual machine and right after allowing the interrupts, the card initiates the Port Status Change Event as the first thing it does.

I will have a look at QEMU's code and see if I can come up with and submit a patch.

Ben
8infy
Member
Member
Posts: 185
Joined: Sun Apr 05, 2020 1:01 pm

Re: QEMU's xHCI doesn't generate port status change on start

Post by 8infy »

BenLunt wrote:
8infy wrote:Hi! No problem.
I haven't looked into it any further.
May I ask if you interact with the port in any way or does it issue status change right after HCI reset
and interrupter/schedule enable?
Thanks
Here is was happens in my driver from time of initialize (unmasking the interrupt) and the Port Change Event:

Code: Select all

131904021959: XHCI: Unmasking IRQ 22
131904021969: XHCI: irq fired
131904021969: XHCI: ED = 0, Type 48, Status 0x00000001
 Found NEC/Renesas firmware version: 30.25
131904021969: XHCI: USB_IRQ_DONE
131904021969: XHCI: irq fired
131904021969: XHCI: USB_IRQ_DONE
 NEC verification via vendor specific command NEC_TRB_TYPE_GET_UN: 131904021971: XHCI: NEC Verification
131904021971: XHCI: irq fired
131904021971: XHCI: ED = 0, Type 48, Status 0x00000001
131904021971: XHCI: USB_IRQ_DONE
131904021971: XHCI: irq fired
131904021971: XHCI: USB_IRQ_DONE
TRUE
131904021971: XHCI: irq fired
131904021971: XHCI: ED = 0, Type 33, Status 0x00000001
131904021971: XHCI: Command Completion Event
131904021971: XHCI: Command 21 Completion: 0x01000000
131904021971: XHCI: USB_IRQ_DONE
131904021971: XHCI: irq fired
131904021971: XHCI: USB_IRQ_DONE
131904021974: XHCI: irq fired
131904021974: XHCI: ED = 0, Type 33, Status 0x00000001
131904021974: XHCI: Command Completion Event
131904021974: XHCI: Command 21 Completion: 0x01000000
131904021974: XHCI: USB_IRQ_DONE
131904021974: XHCI: irq fired
131904021974: XHCI: USB_IRQ_DONE
131904021974: XHCI: irq fired
131904021974: XHCI: ED = 0, Type 33, Status 0x00000001
131904021974: XHCI: Command Completion Event
131904021974: XHCI: Command 21 Completion: 0x01000000
131904021974: XHCI: USB_IRQ_DONE
131904021974: XHCI: irq fired
131904021974: XHCI: USB_IRQ_DONE
131904021976: XHCI: irq fired
131904021976: XHCI: ED = 0, Type 33, Status 0x00000001
131904021976: XHCI: Command Completion Event
131904021976: XHCI: Command 21 Completion: 0x01000000
131904021976: XHCI: USB_IRQ_DONE
131904021976: XHCI: irq fired
131904021976: XHCI: USB_IRQ_DONE
131904021977: XHCI: irq fired
131904021977: XHCI: ED = 0, Type 34, Status 0x00000001
131904021977: XHCI: Port Status Change Event
131904021977: XHCI: USB_IRQ_DONE
However, please note that I check for the NEC card and get its version, as well as the bandwidth command, before the Port Status Change Event takes place.

...

After looking over my code some more, at the point that QEMU fires the Port Status Change Event might be where I start to enumerate the attached devices, which means I reset a port. If this is the case, then the Event might be because of the port reset.

I haven't looked into it very far. Something I will need to look into I guess. There is a possibility that QEMU isn't firing the Event as you stated before.

...

Yep, you are correct. I commented out the code that creates the root hub device, which is the driver that enumerates the attached devices. The code still resets the controller.

QEMU is not firing the Port Status Change Event after the controller reset.

I tried my code in DEBUG mode on an actual machine and right after allowing the interrupts, the card initiates the Port Status Change Event as the first thing it does.

I will have a look at QEMU's code and see if I can come up with and submit a patch.

Ben
Yeah that's the behavior I observed as well!
Thanks
Post Reply