Hi.
I am working on USB support for my OS. I chose UHCI as the first USB controller I'll write a driver for, and I built a generic USB interface on top of it. But when I think of the main reason I want USB support (which is USB keyboards and mice), I hit a wall. USB HID devices normally use interrupt transfers to keep the CPU idle when possible, which works with the same idea as PS/2 IRQs as I understand it. What I don't understand is how can I receive unrequested data using UHCI or any other USB controller? I understand that when I want to send/receive data, I construct transfer descriptors with appropriate information, but how can I let the device send me information I didn't ask for? How would I execute other transfer descriptors on the same USB host controller while it would seemingly be polling for data the device sent?
One more question: is it possible to use this "streaming" mode of USB HID devices without actually enabling PCI IRQs? I don't have a full AML interpreter, and so the PCI interrupt line field is probably not very reliable on some real hardware.
Thanks in advance.
USB interrupt transfers
- BrightLight
- Member
- Posts: 901
- Joined: Sat Dec 27, 2014 9:11 am
- Location: Maadi, Cairo, Egypt
- Contact:
USB interrupt transfers
You know your OS is advanced when you stop using the Intel programming guide as a reference.
Re: USB interrupt transfers
One of the device's descriptors, the Interrupt Descriptor, gives an interval value. Your driver is to request a packet, an interrupt packet, once per interval. For example, if this interval is every 500ms, your driver should request the 3-, 4-, or 5-byte packet every 500ms. If you request it too early, say 400ms and the device hasn't updated it yet, you will either receive a NAK or you will receive the same packet as before. If you request it later, say 600ms, you will receive the next packet.omarrx024 wrote:Hi.
I am working on USB support for my OS. I chose UHCI as the first USB controller I'll write a driver for, and I built a generic USB interface on top of it. But when I think of the main reason I want USB support (which is USB keyboards and mice), I hit a wall. USB HID devices normally use interrupt transfers to keep the CPU idle when possible, which works with the same idea as PS/2 IRQs as I understand it. What I don't understand is how can I receive unrequested data using UHCI or any other USB controller? I understand that when I want to send/receive data, I construct transfer descriptors with appropriate information, but how can I let the device send me information I didn't ask for? How would I execute other transfer descriptors on the same USB host controller while it would seemingly be polling for data the device sent?
One more question: is it possible to use this "streaming" mode of USB HID devices without actually enabling PCI IRQs? I don't have a full AML interpreter, and so the PCI interrupt line field is probably not very reliable on some real hardware.
Thanks in advance.
Anyway, read up on interrupt devices, namely mice and keyboards.
Might I (shamelessly) suggest http://www.fysnet.net/the_universal_serial_bus.htm
Another note is that most BIOS and UHCI hardware will emulate a PS/2 keyboard and mouse until you tell it not to. Therefore, you can continue to use a USB mouse and/or keyboard and a PS/2 driver.
Ben
- BrightLight
- Member
- Posts: 901
- Joined: Sat Dec 27, 2014 9:11 am
- Location: Maadi, Cairo, Egypt
- Contact:
Re: USB interrupt transfers
Thanks for pointing this out for me. It's incredibly stupid of me not to notice the "interval" field of the endpoint descriptor.BenLunt wrote:One of the device's descriptors, the Interrupt Descriptor, gives an interval value. Your driver is to request a packet, an interrupt packet, once per interval. For example, if this interval is every 500ms, your driver should request the 3-, 4-, or 5-byte packet every 500ms. If you request it too early, say 400ms and the device hasn't updated it yet, you will either receive a NAK or you will receive the same packet as before. If you request it later, say 600ms, you will receive the next packet.
I'm sure it would be a great read, but I'm still underage and cannot have a credit card.BenLunt wrote:Might I (shamelessly) suggest http://www.fysnet.net/the_universal_serial_bus.htm
I am aware of this, but natively supporting USB devices has been in my to-do list for too long, and it's time to narrow down the list.BenLunt wrote:Another note is that most BIOS and UHCI hardware will emulate a PS/2 keyboard and mouse until you tell it not to. Therefore, you can continue to use a USB mouse and/or keyboard and a PS/2 driver.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
Re: USB interrupt transfers
As BenLunt pointed out all USB transfers are initiated by the host, so even for interrupt transfers the host is polling the USB device.omarrx024 wrote:One more question: is it possible to use this "streaming" mode of USB HID devices without actually enabling PCI IRQs? I don't have a full AML interpreter, and so the PCI interrupt line field is probably not very reliable on some real hardware.
In addition to that it is not possible to receive USB transaction IRQs (i.e. those IRQs that are triggered by the interrupt-on-completion bit in the TD) without enabling PCI interrupts (or polling the UHCI status register). As long as you're using the legacy PIC you're fine, as the IRQ line register should be reliable. If you're using the APIC, you need a full AML interpreter (or just use ACPICA) and invoke the _PIC and _PRT control methods.
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].