Page 1 of 1
EHCI Asynch Scheduler not advancing
Posted: Mon May 09, 2011 11:10 pm
by bobschriver
I've been working on an EHCI implementation for a school project and I've run into a snag. Up to this point, I believe I have configured all ports and the host controller correctly. However, when I attempt to perform an operation with the async queue, it doesn't advance correctly. Right now I create all of the individual QTD's and link them together, and then I create the QTD Head and link the list of QTD's in through the QTD Head's own QTD, like this:
Code: Select all
struct _qtd_head * head = _create_qtd_head(-1 , device , 0);
head->qtd.next_qtd = setup_qtd;
Where _qtd_head and qtd are defined as the 64bit compatible structures as defined in the EHCI spec.
I receive a Async Transfer interrupt, and printing the current QTD Head at that interrupt shows that the QTD above, setup_qtd, has been loaded into the head->qtd field. However, despite the fact that setup_qtd has a next_qtd, I receive no more interrupts.
Does anybody have any suggestions as to why I would receive no more interrupts?
Thanks!
Re: EHCI Asynch Scheduler not advancing
Posted: Tue May 10, 2011 12:10 pm
by Jonatan44
Could you print USBSTS,USBCMD and all the QTDs tokens status fields in the hangup stage (timeout)?
Re: EHCI Asynch Scheduler not advancing
Posted: Tue May 10, 2011 12:51 pm
by bobschriver
Sure.
Before enabling Async Scheduling:
USBCMD: 80001
USBSTS: 8
My QTD Head:
Current Queue Head: 9fb40
Next QHLP: 9fb42
Endpoint Characteristics: 7040e007
Endpoint Capabilities: 40000000
Current QTD: 0
Current QTD->next_qtd: 9fba0
I enable Async Scheduling with
Code: Select all
*_USBCMD |= ASYNC_ENABLE | ASYNC_ADV_DOORBELL_ENABLE
I immediately receive an interrupt
In the interrupt code
USBSTS: A028
USBCMD: 80021
Current Queue Head: 9fb40
Next QHLP: 9fb42
Endpoint Characteristics: 7040e007
Endpoint Capabilities: 40000000
Current QTD: 9fba0
Current QTD->next_qtd: 9fc00
After handling the interrupt
USBSTS: A000
USBCMD: 80021
Let me know if you need any more information.
Re: EHCI Asynch Scheduler not advancing
Posted: Tue May 10, 2011 1:41 pm
by Jonatan44
Hi,
it seems that the async's set the reclamation bit in USBSTS, but if you still get an timeout check the following:
1)is the "_next" pointer to the incoming qtd valid? is the qtd pointer to the page buffer valid?
2)is the incoming qtd is the last one? if so, doest it's "_next" points to "0x01"?
if non of the above I would like you to print the memory footprints (hex will do the job) of the qtd tokens (io/setup and handshakes) and there pages before and after interrupt handling, also the queue head.
Re: EHCI Asynch Scheduler not advancing
Posted: Tue May 10, 2011 5:58 pm
by bobschriver
Jonatan44 wrote:Hi,
it seems that the async's set the reclamation bit in USBSTS, but if you still get an timeout check the following:
1)is the "_next" pointer to the incoming qtd valid? is the qtd pointer to the page buffer valid?
2)is the incoming qtd is the last one? if so, doest it's "_next" points to "0x01"?
if non of the above I would like you to print the memory footprints (hex will do the job) of the qtd tokens (io/setup and handshakes) and there pages before and after interrupt handling, also the queue head.
The _next pointer of the incoming qtd is a valid qtd pointer. The page buffer pointer is also appears to be a valid adress, so the worst that will be in there is zero's. The incoming qtd is not the last one, it's next is also set.
Before the interrupt:
qtd_head: CD7FFB40
Next QHLP: CD7FFB42
Endpoint Characteristics: F040E007
Endpoint Capabilities: 40000000
Curr QTD: 0
the Next QTD field in the QTD struct in qtd_head is set to CD7FFBA0
Setup QTD: CD7FFBA0
Next QTD: CD7FFC00
Alternate QTD: 1
QTD Token: 88280
IN QTD: CD7FFC00
Next QTD: CD7FFC40
Alternate QTD: 1
QTD Token: 80128180
OUT QTD: CD7FFC40
Next QTD: 1
Alternate QTD: 1
QTD Token 8880
After interrupt
qtd_head: CD7FFB40
Next QHLP: CD7FFB42
Endpoint Characteristics: F040E007
Endpoint Capabilities: 40000000
Curr QTD: CD7FFBA0
Setup QTD: CD7FFBA0
Next QTD: CD7FFC00
Alternate QTD: 1
QTD Token: 88280
IN QTD: CD7FFC00
Next QTD: CD7FFC40
Alternate QTD: 1
QTD Token: 80128180
OUT QTD: CD7FFC40
Next QTD: 1
Alternate QTD: 1
QTD Token 8880
It seems like its just loading the current qtd into the qtd head and then not proceeding.
I was doing some other testing, and the same problem occurs when I load in a list of blank QTD's, however when I attempt to attach another QTD head, I receive a PCI master abort. Is this possibly related?
Re: EHCI Asynch Scheduler not advancing
Posted: Fri May 13, 2011 12:44 am
by bobschriver
After fiddling around a little bit, I decided to set the CErr field in the Setup QTD token to three, just to see if any errors were occurring. After enabling the Async schedule and "ringing the doorbell", I immediately receive a USB Error interrupt.
The content of the QTD token is:
0x80248
indicating there was an error and the transaction is halted.
The PCI Status register is
0x2980
Indicating there was a parity error.
I believe this to be the reason my Asynchronous queue is halting, but does anyone have a clue as to why this error would occur?
Thanks.
Re: EHCI Asynch Scheduler not advancing
Posted: Fri May 13, 2011 3:17 am
by Jonatan44
if you have a usb bus tracer it would be really helpful in this situation.
Can you tell more about you hardware configuration? what is your device speed? what is the setup request you wish to perform (SET_ADDR,GET_CONF,..) and if there is a hub in the middle?
Re: EHCI Asynch Scheduler not advancing
Posted: Sat May 14, 2011 10:37 pm
by bobschriver
Jonatan44 wrote:if you have a usb bus tracer it would be really helpful in this situation.
Can you tell more about you hardware configuration? what is your device speed? what is the setup request you wish to perform (SET_ADDR,GET_CONF,..) and if there is a hub in the middle?
First I should note that I am not actually receiving a parity error, that was a mistake on my part. The PCI status register shows nothing out of the ordinary.
Right now I am plugging a high speed device into the root hub. My computer uses the Intel ICH7 IO chip, and I am just using a standard HP flash drive to test. I am attempting to send a GET_DESCRIPTOR request, asking for the DEVICE information. My request looks like this:
0x8006010000001200
When I look at the token after the scheduler has halted, the Xact Err token is set, the Halted bit in status is set, and my Error Counter is decremented to zero. This makes me think that I am formatting my request incorrectly, but I don't see anything wrong with it, though I made be wrong.
Another interesting bit which may help, when I plug the USB drive into the debug port (PORT 0), the schedule advances one more token to my input request and then halts, however in this case my error counter is incremented, for some reason.
Thanks for your help so far.
Re: EHCI Asynch Scheduler not advancing
Posted: Sun May 15, 2011 12:09 pm
by Jonatan44
Code: Select all
OUT QTD: CD7FFC40
Next QTD: 1
Alternate QTD: 1
QTD Token 8880
is an handshak token - 1000100010000000 means:
status 0x80 (token not handled yet), out packet, cerr = 3,
length = 4, toggle bit off
as i recall the toggle bit should be set, and the legnth in a handshak packet should be zero.
Re: EHCI Asynch Scheduler not advancing
Posted: Sun May 15, 2011 6:37 pm
by bobschriver
Jonatan44 wrote:Code: Select all
OUT QTD: CD7FFC40
Next QTD: 1
Alternate QTD: 1
QTD Token 8880
is an handshak token - 1000100010000000 means:
status 0x80 (token not handled yet), out packet, cerr = 3,
length = 4, toggle bit off
as i recall the toggle bit should be set, and the legnth in a handshak packet should be zero.
You are right about the toggle bit, and that is now set. This hasn't changed my current situation.
But if I understand the specification correctly, length is set in the 16th -> 30th bit, and the 15th bit being set indicates that I want an interrupt on completion. I could be reading it wrong or have an incorrect version.
Also, I should mention about my previous post, the SETUP transaction is a little backwards. I print the least significant byte first, so it goes like this:
Byte Value
00 80
01 06
02 01
etc.
Sorry for any confusion.
Re: EHCI Asynch Scheduler not advancing
Posted: Tue May 17, 2011 12:42 pm
by Jonatan44
Hi.
But if I understand the specification correctly, length is set in the 16th -> 30th bit, and the 15th bit being set indicates that I want an interrupt on completion. I could be reading it wrong or have an incorrect version.
your right,my mistake.
except the toggle bit issue, you QTDs looks fine, could you post here you queue head memory structure?
Re: EHCI Asynch Scheduler not advancing
Posted: Tue May 17, 2011 6:00 pm
by bobschriver
Jonatan44 wrote:Hi.
But if I understand the specification correctly, length is set in the 16th -> 30th bit, and the 15th bit being set indicates that I want an interrupt on completion. I could be reading it wrong or have an incorrect version.
your right,my mistake.
except the toggle bit issue, you QTDs looks fine, could you post here you queue head memory structure?
Here's my current QTD Head Struct:
Code: Select all
struct _qtd_head
{
uint32_t qhlp;
uint32_t device_address: 7;
uint32_t inactive: 1;
uint32_t endpoint: 4;
uint32_t endpoint_speed: 2;
#define EPS_HIGH_SPEED 0x02
uint32_t data_toggle: 1;
uint32_t H: 1;
uint32_t max_packet_length: 11;
uint32_t control_edndpoint_flag: 1;
uint32_t nak_count_reload: 4;
uint8_t interrupt_schedule_mask;
uint8_t split_completion_mask;
uint16_t hub_address: 7;
uint16_t port_number: 7;
uint16_t mult: 2;
uint32_t curr_qtd;
struct _qtd qtd;
} __attribute__((packed));
I ran a few more tests, and it seems that I am not receiving NAK's from my setup request because the NAK count in the qtd head is the same as the NAK reload. However, both the Halted bit and the XactErr bit are set, as well as Cerr being decremented which indicate that I've received some sort of error that is not a NAK. I've looked at the spec, and I'm not sure what error I could be receiving doing a simple setup transaction.
Re: EHCI Asynch Scheduler not advancing
Posted: Fri May 20, 2011 3:42 am
by Jonatan44
Hi, i meant the queue head structure memory buffer..