UHCI failing to raise IRQ on real HW
Posted: Wed Jun 16, 2010 12:34 am
I have a driver for UHCI which is operating on a real machine, able to enumerate devices and even able to read sectors off a mass storage device that is connected to a hub.
What I can't do is get the HC to deliver an IRQ to the CPU on real HW -- but it does work fine on QEMU and Bochs.
I disable EHCI. I have USBINTR=0x0F (fully enabled). I have PCICMD=0x05 (Bus master, interrupt, and I/O enable). I have all the USB registers set up correctly -- enough to do transfers just fine with polling.
The INT_LN=9 and INT_PIN=D and I have an ACPI IRQ redirection entry from 9 to 9 (level triggered, active high). I have configured the IO-APIC entry 9 to broadcast to logical destination 0xFF, level-triggered, active-high, and CPU vector 0x50 using the same code I use successfully for all my other drivers.
I have tried all kinds of settings to USB_LEGKEY, enabling and disabling the USBPIRQEN bit, clearing the R/WC bits. Linux seems to enable USBPIRQEN, but other I've seen other code snippets that don't set it. I do notice that the system likes to set the "SMI caused by USB interrupt" bit, even though I have done nothing to allow that. Not sure if that is the problem though.
I have the timer interrupt run a function which checks USB status and starts an operation with IOC bits set. The USB status bits for IOC are being toggled correctly, which is supposed to generate an IRQ. It repeatedly and correctly completes the transaction, but no dice with the IRQ. I also tried causing a HC halt, which is supposed to generate an error and an IRQ.
This is what Linux says about the HC:
I spent the day scouring the Internet, to no avail. I'm not sure what to try next. Any ideas?
What I can't do is get the HC to deliver an IRQ to the CPU on real HW -- but it does work fine on QEMU and Bochs.
I disable EHCI. I have USBINTR=0x0F (fully enabled). I have PCICMD=0x05 (Bus master, interrupt, and I/O enable). I have all the USB registers set up correctly -- enough to do transfers just fine with polling.
The INT_LN=9 and INT_PIN=D and I have an ACPI IRQ redirection entry from 9 to 9 (level triggered, active high). I have configured the IO-APIC entry 9 to broadcast to logical destination 0xFF, level-triggered, active-high, and CPU vector 0x50 using the same code I use successfully for all my other drivers.
I have tried all kinds of settings to USB_LEGKEY, enabling and disabling the USBPIRQEN bit, clearing the R/WC bits. Linux seems to enable USBPIRQEN, but other I've seen other code snippets that don't set it. I do notice that the system likes to set the "SMI caused by USB interrupt" bit, even though I have done nothing to allow that. Not sure if that is the problem though.
I have the timer interrupt run a function which checks USB status and starts an operation with IOC bits set. The USB status bits for IOC are being toggled correctly, which is supposed to generate an IRQ. It repeatedly and correctly completes the transaction, but no dice with the IRQ. I also tried causing a HC halt, which is supposed to generate an error and an IRQ.
This is what Linux says about the HC:
00:1d.0 USB Controller: Intel Corporation N10/ICH7 Family USB UHCI Controller #1 (rev 01) (prog-if 00 [UHCI])
Subsystem: Dell Unknown device 01de
Flags: bus master, medium devsel, latency 0, IRQ 225
I/O ports at ff80
I spent the day scouring the Internet, to no avail. I'm not sure what to try next. Any ideas?