QEMU's xHCI doesn't generate port status change on startup
QEMU's xHCI doesn't generate port status change on startup
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!
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!
Re: QEMU's xHCI doesn't generate port status change on start
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
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
Re: QEMU's xHCI doesn't generate port status change on start
Hi, thanks for your reply!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
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.
Re: QEMU's xHCI doesn't generate port status change on start
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.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.
Thanks,
Ben
Re: QEMU's xHCI doesn't generate port status change on start
Thank you!BenLunt wrote: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.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.
Thanks,
Ben
Re: QEMU's xHCI doesn't generate port status change on start
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.
Re: QEMU's xHCI doesn't generate port status change on start
Hi and sorry for the long delay.BenLunt wrote: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.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.
Thanks,
Ben
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
Ben
Re: QEMU's xHCI doesn't generate port status change on start
Hi! No problem.BenLunt wrote:Hi and sorry for the long delay.BenLunt wrote: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.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.
Thanks,
Ben
I ran a few tests and QEMU does indeed issue a Port Status Change Event when a device is connected at startup.Have you been able to progress on this?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
Ben
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
Re: QEMU's xHCI doesn't generate port status change on start
Here is was happens in my driver from time of initialize (unmasking the interrupt) and the Port Change Event: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
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
...
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
Re: QEMU's xHCI doesn't generate port status change on start
Yeah that's the behavior I observed as well!BenLunt wrote:Here is was happens in my driver from time of initialize (unmasking the interrupt) and the Port Change Event: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?
ThanksHowever, 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.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
...
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
Thanks