[Solved] OHCI Controller Never Responds
Posted: Tue May 23, 2017 5:18 pm
The title says it all. I'm trying to implement OHCI SETUP transfers, which my USB layer uses to detect attached devices. However, the OHCI always times out, without any relevant error or anything. In Bochs, the OHCI activity indicator never lights up, so I guess the OHCI somehow doesn't execute the descriptors at all.
To reset the OHCI, I set the "reset" bit in the Command/Status register and poll it until it clears. Then, I reset and enable all ports on the root hub, by setting the "port reset" bit, polling it until it clears, and then setting the "port enable" bit.
My EDs and TDs look correct.
I tell the device to execute the descriptors like this:
I then poll the controller, waiting for any error bits to set, or ED's "head TD" field to be equal to the "tail TD" field, but the "head TD" field is never changed, and no errors are set either, and the ED's completion code stays zero, and the controller is apparently not even doing anything. Is there something I am missing here?
EDIT: I managed to get it working in QEMU. I forgot to set the controller's operational mode in the control register. However, in Bochs, it is still the same, with no sign of it working at all. I've updated the code snipped shown above.
To reset the OHCI, I set the "reset" bit in the Command/Status register and poll it until it clears. Then, I reset and enable all ports on the root hub, by setting the "port reset" bit, polling it until it clears, and then setting the "port enable" bit.
My EDs and TDs look correct.
Code: Select all
ED @ 0x0181A000:
00202000
F0000000
0181A010
00000000
TD1 @ 0x0181A010:
02000000
0000F8E8
0181A020
0000F8EF
TD2 @ 0x0181A020:
03100000
0000F8F0
0181A030
0000F901
TD3 @ 0x0181A030:
02080000
00000000
F0000000
00000000
Code: Select all
; disable control list execution
mov edi, [.mmio]
mov eax, [edi+OHCI_CONTROL]
and eax, not OHCI_CONTROL_EXECUTE_CONTROL
mov [edi+OHCI_CONTROL], eax
; clear the communications area
mov edi, [ohci_comm]
mov eax, 0
mov ecx, 256
rep stosb
; send the address of the communications area
mov eax, [ohci_comm]
call virtual_to_physical
mov edi, [.mmio]
mov [edi+OHCI_COMM], eax
; send the address of the ED
mov edi, [.mmio]
mov eax, [.descriptors_phys]
mov [edi+OHCI_CONTROL_HEAD_ED], eax
mov eax, 0
mov [edi+OHCI_CONTROL_CURRENT_ED], eax
; control list filled
mov edi, [.mmio]
mov eax, [edi+OHCI_COMMAND]
or eax, OHCI_COMMAND_CONTROL_FILLED
mov [edi+OHCI_COMMAND], eax
; enable execution
mov edi, [.mmio]
mov eax, [edi+OHCI_CONTROL]
or eax, OHCI_CONTROL_EXECUTE_CONTROL
mov ebx, 2 ; operational mode
shl ebx, 6
or eax, ebx
mov [edi+OHCI_CONTROL], eax
EDIT: I managed to get it working in QEMU. I forgot to set the controller's operational mode in the control register. However, in Bochs, it is still the same, with no sign of it working at all. I've updated the code snipped shown above.