Re: Setting up EHCI queue heads
Posted: Sun Aug 06, 2017 4:40 pm
Are there some other fields in QH/TD that need to be set, like the NAK stuff?
The Place to Start for Operating System Developers
http://f.osdev.org/
Again, sorry, I don't have the time at the moment to look over your code. However, dump your Queue Head and TD's to DWORDs and post that.mariuszp wrote:bump?
Code: Select all
0x01234567 <- Queue Head at address 0x76543210
0x87763873 <- TD0 (Setup Packet) at address 0x82349238
(setup packet contains: 00 00 00 00 00 00 00 00) and is at address 0x23422837
0x82839492 <- TD1 (Status Packet) at address 0x8394832
Code: Select all
Queue Head (before horizontal pointer is set):
0x01D5E002
0x0040A000
0x40000000
0x00000000
0x00000001
0x00000001
0x00000000
0x00000000
0x00000000
0x00000000
0x00000000
0x00000000
First TD (SETUP at phys 0x01D5F000):
0x01D5F020
0x00000001
0x00080280
0x01D5F040
0x00000000
0x00000000
0x00000000
0x00000000
Second TD (STATUS at phys 0x01D5F020):
0x00000001
0x00000001
0x00000180
0x00000000
0x00000000
0x00000000
0x00000000
0x00000000
SETUP packet data at phys 0x01D5F040:
0x00010500
0x00000000
Code: Select all
Queue Head (before horizontal pointer is set):
0x01D5E002 horzontal pointer and it is pointing to another QH
0x0040A000 max len = 0x40, Head = 1, DTC = 0 (see note '1' below), EPS = HS, Endp = 0, Addr = 0
0x40000000 1 transaction per microframe
0x00000000 zero
0x00000001 currently no TD linked
0x00000001 currently no alt TD linked
0x00000000 zeros
0x00000000
0x00000000
0x00000000
0x00000000
0x00000000
First TD (SETUP at phys 0x01D5F000):
0x01D5F020 next TD (correct address)
0x00000001 no alt TD
0x00080280 DT = 0, bytes to transfer = 8, IOC = 0, CPAGE = 0, CERR = 0 (see note '2'), PID = SETUP, Status = 0x80
0x01D5F040 buffer pointer/current offset (correct)
0x00000000
0x00000000
0x00000000
0x00000000
Second TD (STATUS at phys 0x01D5F020):
0x00000001 Done, no more TD's
0x00000001 no alt TD
0x00000180 DT = 0 (see note '3'), bytes to transfer = 0, IOC = 0, CPAGE = 0, CERR = 0 (see note '2'), PID = IN, Status = 0x80
0x00000000
0x00000000
0x00000000
0x00000000
0x00000000
SETUP packet data at phys 0x01D5F040:
0x00010500
0x00000000
If the above is little endian: (and it should be)
00 = (HOST_TO_DEV | REQ_TYPE_STNDRD | RECPT_DEVICE)
05 = Set Address
01 00 = address 1
00 00 = index = 0
00 00 = len = 0
1: A DTC of zero means to ignore the toggle bit in the TD and start with this one. I would set
this bit to 1 and use the Toggle bits within the TD's instead.
2: I would make the CERR field = 3.
3: All STATUS TD's need a DT of '1'
The SETUP packet has a Data Toggle of '0', then the STATUS packet has a DT of '1'
Code: Select all
Queue Head (before horizontal pointer is set):
0x01D5E002
0x0040E000
0x40000000
0x00000000
0x00000001
0x00000001
0x00000000
0x00000000
0x00000000
0x00000000
0x00000000
0x00000000
First TD (SETUP at phys 0x01D5F000):
0x01D5F020
0x00000001
0x00080E80
0x01D5F040
0x00000000
0x00000000
0x00000000
0x00000000
Second TD (STATUS at phys 0x01D5F020):
0x00000001
0x00000001
0x80000D80
0x00000000
0x00000000
0x00000000
0x00000000
0x00000000
SETUP packet data at phys 0x01D5F040:
0x00010500
0x00000000
This is not always the case. I have a thumb drive that is full-speed only. Yes, most devices now are high-speed if not super-speed, but there are still devices that are full-speed only. Cheaper to manufacture.mariuszp wrote:I set all CERR to 3, DTC in the queue head to 1, and DT in sETUP to 0, DT in STATUS to 1. However, the problem still arises: it clears the 'active' bit and sets the 'transaction error' bit.
The device in question is a USB Flash Memory. According to the wiki those operate at high-speed so AFAIK i should have no problem with using them with EHCI.
It has been a little while since I have worked with EHCI, so I would have to pull my notes out and have a look. (I don't have the time at the moment).mariuszp wrote:But anyhow, how would I detect that the port must be released? USB 1.0 devices cannot handle high-speed, so does that mean i'd have to detect a transaction error and then release the port? (And in that case, does OHCI/UHCI see that something was just connected to the port and issue a "port change" interrupt?)
EDIT 2: In addition to this, CERR is not decremented. This is very confusing.
And furthermore, the Queue Head advances (by checking the "current TD" value, I see that it reaches the STATUS packet).
Code: Select all
sleep(100);
ehciRegs->ports[i] |= EHCI_PORT_RESET;
sleep(50);
ehciRegs->ports[i] &= ~EHCI_PORT_RESET;
Code: Select all
ehciRegs->ports[i] |= EHCI_PORT_RESET;
while (ehciRegs->ports[i] & EHCI_PORT_RESET);
if ((ehciRegs->ports[i] & EHCI_PORT_ENABLED) == 0)
{
kprintf("ehci: warning: not high-speed\n");
// TODO: port routing
continue;
};
Code: Select all
Queue Head (after transaction):
0x01D5E002
0x0040E000
0x40000000
0x01D5F020
0x00000001
0x00000001
0x80000D08
0x00000000
0x00000000
0x00000000
0x00000000
0x00000000
First TD (SETUP at phys 0x01D5F000, after transaction):
0x01D5F020
0x00000001
0x00080E08
0x01D5F040
0x00000000
0x00000000
0x00000000
0x00000000
Second TD (STATUS at phys 0x01D5F020, after transaction):
0x00000001
0x00000001
0x80000D08
0x00000000
0x00000000
0x00000000
0x00000000
0x00000000
SETUP packet data at phys 0x01D5F040:
0x00010500
0x00000000
I just sent you something very similar in a PM. You can either reply here or in a message. I couldn't post the link publicly as it is on a server that cannot be overloaded too much.BenLunt wrote:Can you make a bootable floppy image, narrowing down the code, printing a line:
"To start the EHCI initialization, press a key"
Then wait for a key press before you start the EHCI stuff.
Then post that floppy image somewhere, or let me know and I can send you an email address. When I get a chance, I can run it through some of my tests and see what is going on.
Ben