USB interrupt transfers

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
BrightLight
Member
Member
Posts: 901
Joined: Sat Dec 27, 2014 9:11 am
Location: Maadi, Cairo, Egypt
Contact:

USB interrupt transfers

Post by BrightLight »

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.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: USB interrupt transfers

Post by BenLunt »

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.
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.

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
User avatar
BrightLight
Member
Member
Posts: 901
Joined: Sat Dec 27, 2014 9:11 am
Location: Maadi, Cairo, Egypt
Contact:

Re: USB interrupt transfers

Post by BrightLight »

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.
Thanks for pointing this out for me. It's incredibly stupid of me not to notice the "interval" field of the endpoint descriptor. :oops:
BenLunt wrote:Might I (shamelessly) suggest http://www.fysnet.net/the_universal_serial_bus.htm :-)
I'm sure it would be a great read, but I'm still underage and cannot have a credit card.
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.
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. :P
You know your OS is advanced when you stop using the Intel programming guide as a reference.
Korona
Member
Member
Posts: 1000
Joined: Thu May 17, 2007 1:27 pm
Contact:

Re: USB interrupt transfers

Post by Korona »

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.
As BenLunt pointed out all USB transfers are initiated by the host, so even for interrupt transfers the host is polling the USB device.

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].
Post Reply